4.1 Q 房网爬虫实例

爬虫实战-爬取 Q 房网
前 3 章已经介绍了编写简单爬虫的基础知识,这一节通过爬虫实例讲解爬取一个具体网站的各种技巧。
4.1.1 网站页面分析
本节爬取的目标网站是深圳 Q 房网(http://shenzhen.qfang.com/),要爬取二手房房源的小区、户型、面积、区域、总价及房源特色,并把这些信息保存到计算机上。
要爬取一个网站,首先要仔细分析它的页面特点和 URL 构造规律。图 4-1 所示为 Q 房网(深圳)的二手房页面。

图 4-1 Q 房网(深圳)的二手房页面
可以看到每页上有 30 套房源,单击底部的翻页跳转到房源第二页,URL 变为 http://shenzhen.qfang.com/sale/f2。继续单击第三页,看到 URL 变为 http://shenzhen.qfang.com/sale/f3。
读者应该看得出来二手房页面 URL 的构造特点,那就是跟在 f 后面的是页码。如果想验证这个规律,可以直接将 URL 中的页码改为某一个数字,例如改为 54,看到打开的页面的确是第 54 页。那么第一页是否也满足这样的规律呢?打开 http://shenzhen.qfang.com/sale/f1。
可以看到这正是二手房房源的首页。至此,已经找到了 URL 的构造规律,可以利用这个规律对多个页面进行爬取。这次为了简单,可以爬取 10 页,也就是 300 条房源信息。
要爬取的数据包括二手房房源的小区、户型、面积、区域、总价及房源特色,下面分析页面,看看这些数据分布在页面的什么位置。图 4-2 所示的是页面中的一套房源。

图 4-2 页面中的一套房源
从这一条房源信息很容易看到,房源题目包含小区名称和房源特色介绍,下面一行包含户型和面积,单价和总价在靠右边的位置,板块在更下一行。从这里可以看出,房源列表页面已经包含所需要爬取的所有数据,因此爬虫只需要爬取房源列表页面即可,不需要爬取房源详情页面。
页面分析到此结束,下面可以开始编写代码了。
4.1.2 编写 Q 房网二手房房源爬虫代码
首先导入 Requests 库和 Lxml 库。这里准备把数据保存为 csv 格式,因此还需要导入 csv 模块。为了控制爬行速度,还需要导入 time 模块,控制爬行速度的目的主要是防止被 Q 房网的服务器反爬虫禁止。
from lxml import etree import requests import csv import time
然后定义抓取函数。这里专门定义一个爬取和解析数据的函数。在第 2 章爬虫基础中曾讲过,服务器会通过读取请求头部的用户代理(User Agent)信息,来判断这个请求是正常的浏览器还是爬虫。为防止被服务器反爬虫禁止,函数里还要定义一个头部。
def spider():
#定义爬虫头部
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)\
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/46.0.2490.80 Safari/537.36'}
#这里使用 for 循环构造前 10 页 URL 地址并 GET 请求下来
#为了防止爬行速度过快,在每一次 GET 后,等待 2 秒
pre_url = 'http://shenzhen.qfang.com/sale/f'
for x in range(1,11):
html = requests.get(pre_url+str(x), headers=headers)
time.sleep(2)
#用获取到的页面初始化 etree,得到一个 selector,
#然后在这个 selector 上使用 XPath 提取数据
selector = etree.HTML(html.text) 到这里已经爬取了房源列表页,每一个房源列表页上有 30 套(也可能少于 30 套,如最后一页)房源,每一套房源上都包含一组所需要的信息。提取出这些房源数据有一个常用技巧:先提取每套房源整体的代码段,然后从中解析出每套房源的具体信息。也就是说,应该先获得每一套房源的 HTML 源码,然后从这一段 HTML 源码里面解析出来这套房源的详细信息。
先来获取每一套房源的代码段。可以借助 Chrome 浏览器的“检查”功能,看看如何获取每一套房源的代码段。在页面空白处单击右键,在弹出的菜单中选择“检查”,使用左上角的选择箭头选中一套房源,如图 4-3 所示。

图 4-3 查看每套房源的 XPath 路径
很明显,这里有很多<li>标签,把鼠标移动到第二个<li>标签,就会发现第二套房源信息变为蓝色,这样就知道每一个<li>标签里就是一套房源的代码。使用 Chrome 浏览器复制第一个<li>标签的 XPath,就会得到类似下面的 XPath 路径。
//*[@id="cycleListings"]/ul/li[1]
如果把路径<li>后面的序号去掉,就得到了<ul>标签下所有<li>标签的路径,可以在 HTML 代码中查看确认一下<ul>标签下的所有<li>标签是否均是房源、没有其他内容的<li>标签。经过确认,可以得到房源列表的 XPath 路径为//*[@id="cycleListings"]/ul/li。
使用这个 XPath 路径提取出来的,就是这一页中每套房源的代码段组成的一个列表,然后对这个列表做一个循环,在每一套房源的代码片段上再次使用 Xpath,取出每套房源的具体信息,按这个思路继续写代码。
#先获取房源列表
house_list = selector.xpath("//*[@id='cycleListings']/ul/li")
for house in house_list:
apartment = house.xpath("div[1]/p[1]/a/text()")[0]
house_layout = house.xpath("div[1]/p[2]/span[2]/text()")[0]
area = house.xpath("div[1]/p[2]/span[4]/text()")[0]
region = house.xpath("div[1]/p[3]/span[2]/a[1]/text()")[0]
total_price = house.xpath("div[2]/span[1]/text()")[0] 这里要注意,在 for 循环里使用的 XPath 路径是相对路径,也就是取出的<li>标签下的路径。要写出正确的相对路径有一个技巧:从 Chrome 浏览器里面复制的第一套房源代码段的 XPath 路径如下。
//*[@id="cycleListings"]/ul/li[1]
复制出的这套房源户型的 XPath 路径如下。
//*[@id="cycleListings"]/ul/li[1]/div[1]/p[2]/span[2]
通过比对这两个路径,很容易知道户型在房源码中的 XPath 相对路径是 div[1]/p[2]/span[2]。
这样就很容易写出代码段中的相对 XPath 路径。
继续把爬取的数据构造成一个 list,然后使用 data_writer 这个保存函数写入计算机中。
item = [apartment, house_layout, area, region, total_price]
data_writer(item) #保存数据
print('正在抓取', xiaoqu) 函数最后使用 print 打印出正在抓取的小区名称,作为爬虫的运行提示。
4.1.3 保存爬取到的信息
可以把获取到的每一套房源信息组成一个 list,保存到 csv 文件里,为了方便复用,这里直接写一个保存函数 data_writer,这个函数接受一个列表,然后使用 csv 的 writerow 方法写入一条记录。
def data_writer(item):
with open('qfang_ershoufang.csv', 'a',
encoding='utf-8', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(item) 首先以追加(a)的方式打开一个 csv 文件(如果没有,系统会新建一个),设置编码方式为 encoding='utf-8',为了防止 csv 文件在每次打开添加数据的时候插入空行,设置 newline=''。
最后编写主函数。
if __name__ == '__main__': spider()
以上就是一个非常简单的爬虫,读者可以在 PyCharm 中运行这段爬虫代码,查看一下爬取的结果。
通过这个例子的学习,读者应该对编写简单爬虫有了一个大概的思路,可以尝试爬取其他相似的栏目做练习,如爬取 Q 房网的租房栏目的房源信息等。最后要提醒读者的是,在爬取一个网站的时候,应该尽量克制爬取速度,一方面是防止被服务器发现,另一方面,爬取行为不可以占用太多服务器资源而影响网站正常用户的访问。因此,可以在代码中使用 time.sleep() 进行等待时间控制,人为地控制爬虫的爬取速度。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论