1 引言
- 最近写了一些简单的爬虫,感觉到爬虫这个东西实践大于理论,需要实际操作才能体会更深,写下这篇短文,希望给有需要的同学在爬虫入门的时候一点小小的帮助。
- 本文适合具备一定Python基础的同学,需要用到包括列表,循环,函数,文件读写等基础知识,没有接触过Python的同学突击了解一下即可,动手为先。
2 环境
- Python3.6
- IDE: Pycharm
- 操作系统:Windows
3 基础知识
本节介绍Requests库和BeautifulSoup库的基本用法,已经有了解的同学可以直接跳过。
我们的目标网页如下图所示,我们想要把红色方框里的数据爬下来,单独整理成一行,这样就形成了每个楼盘一条记录,就方便后续作分析了。
其实,这些数据都在网页源代码里躺着,我们第一步需要做的得到源代码,然后再去源代码里找数据,想要得到网页源代码,本文介绍使用python的requests库:
-
Requests
在Chrome浏览器中,适用Ctrl+u快捷键可以看到网页的源代码,我们的目标数据就在那一大串源代码里。日常浏览的时候,我们通过浏览器获得网页的源代码,经浏览器解析和渲染后,就成了我们看到的模样。
现在我们需要在Python里同样获得源代码,本文使用第三方库Requests,通过以下命令,就可以获得我们需要的源代码了。
# requests.get可以返回一个python response对象
response = requests.get("https://bj.lianjia.com/ershoufang/")
# response对象是二进制的,我们需要通过.text方法将它转化成文本,转化之后就是Ctrl+u看到的样子
response_text = response.text
获得源代码以后,我们要进一步在源代码里找到我们需要的数据,网页的源代码是有一定的结构的,类似
<li class="sellListContent"> 目标数据 </li>
这样的结构是一个个标签,但是我们在上一步获得的源代码是一个超长的字符串,我们需要将字符串重新转化为有结构的模式,这里使用第三方库BeautifulSoup。
- BeautifulSoup
BeautifulSoup库可以将源代码转化为BeautifulSoup对象,我们需要在BeautifulSoup对象中找到我们的目标标签,然后提取目标数据,代码如下
from bs4 import BeautifulSoup # python3已将BeautifulSoup库集成到bs4中,需要先import
# 将上述文本转化为BeautifulSoup对象,"html.parser"是一种解剖器
bsobj = BeautifulSoup(response_text,"html.parser")
# 在BeautifulSoup对象里找到目标内容所在的标签
ul = bsobj.find("ul",{"class":"sellListContent"}) # 这里.find返回找到的第一个标签
# 由于标签是有层级结构的,所以我们可以继续在标签里找,这里.find_all则返回找到的所有符合要求的标签组成的列表
all_li = ul.find_all("li",{"class":"clear"})
基础知识介绍到这里,下面开始实战。
4 开始爬虫
本节定义了几个函数,实现了从标签里提取数据,并拼接成我们需要的格式,然后写入文本文件。下面分别介绍:
- 函数getdata(),从网页爬取数据
我们期望实现以下效果:给函数一个网址,函数就返回我们需要的数据,代码如下
import requests
from bs4 import BeautifulSoup
def getdata(url):
# 模拟一个请求头,目的是假装我们是通过浏览器访问的网页
header = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36"}
# 通过requests.get可以获得网址为url的网页的返回的一些数据
response = requests.get(url,headers=header)
# 由于返回的是二进制,需要通过response.text转化为文本
response_text = response.text
# 将上述文本转化为BeautifulSoup对象,"html.parser"是一种解剖器
bsobj = BeautifulSoup(response_text,"html.parser")
# 在BeautifulSoup对象里找到目标内容所在的标签
ul = bsobj.find("ul",{"class":"sellListContent"})
# 再在标签里找到下级标签,返回的是所有标签组成的一个列表(也可以在上一步直接找,不过有可能找到一些包含我们不需要的数据的标签)
all_li = ul.find_all("li",{"class":"clear"})
housdata = []
# 由于每一个"li"都是一条记录,我们要循环将"li"里面的内容取出来
for li in all_li:
record = ""
# 由于每一个"li"里面又有很多"div","div"里的内容才是我们真正想要的,因此继续找
all_div = li.find("div",{"class":"info clear"}).find_all("div")
# 将每个"div"里的内容通过.get_text()方法取出来
for j in all_div:
j_text = j.get_text().strip().strip("\n") # 两个strip先后去除取出来文本两端的空格和换行符
# 然后将每个"div"里取出来的文本拼接起来
record = record + "@" + j_text
# 每个"li"都会返回一个record,即一条记录
# 将每个record都添加到housdata这个列表里
housdata.append(record)
# 最后返回整个housdata列表
return housdata
定义好这个函数之后,我们每输入一个url,函数就可以返回包括该网页中所有记录的列表了。
当然,一个页面并不能满足要求,我们的目标是所有网页,因此只需要得到所有网页,然后一个一个喂给getdata函数就可以了,下面定义一个构造网页的函数,我们给该函数一个数字(代表第几页),该函数就返回该页的网址。
- 函数geturl(),获取页面url
def geturl(num):
if num ==1 :
url = r"https://bj.lianjia.com/ershoufang/"
else:
url = "https://bj.lianjia.com/ershoufang/pg" + str(num) +"/"
return url
- 最后的工作
最后就是使用我们定义好的函数,然后一页一页爬取,并写入txt文本文件了。
lianjia = open(r"C:\Users\lianjia.txt","a",encoding="utf-8")
for i in range(1, 940):
url = geturl(i)
housdata = getdata(url)
for line in housdata:
lianjia.write(line + "\n")
time.sleep(1)
print(i)
lianjia.close()
转载请注明出处,有任何问题,请联系我的邮箱:oythonhill@163.com