4.2 多层页面的爬取
4.2.1 爬取详情页面分析
4.1 节编写的 Q 房网二手房房源爬虫,仅仅爬取到了房源列表页面显示的房源信息,如果需要的房源信息只能在房源详情页面中看到,就需要爬虫除了能够爬取房源列表页面,还要能够从房源列表页面中提取出房源详情页面的 URL,并爬取房源详情页面,以获取相关数据。
下面分析一下页面。这次希望在 4.1 节爬取的数据基础上增加房屋年限、抵押信息等数据。这些数据只有在房源详情页面中才能看到,图 4-4 所示为一套房源的详情页面。

图 4-4 一套房源的详情页面
可以看到“交易属性”这个栏目包含了房屋年限和抵押信息。只有让爬虫爬取房源详情页面的 URL,GET 详情页面后,才能抓取到这些信息。需要在房源列表页面中提取房源详情页面的 URL,先使用 Chrome 浏览器的“检查”功能分析一下,如图 4-5 所示。

图 4-5 分析提取详情页 URL
我们看到房源标题所在的<a>标签里的 href 属性就是房源详情页面的部分 URL,即/sale/100113959?insource=sale_list。
可以在前面加上 http://shenzhen.qfang.com,从而构造出完整的房源详情页 URL,根据这个思路开始写代码。
4.2.2 编写爬取详情页面的代码
首先,导入需要的包,定义用户代理及网址前缀等常量。
import requests
from lxml import etree
import csv
import time
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'}
pre_url = 'http://shenzhen.qfang.com/sale/f' 因为爬虫要爬取房源列表和房源详情两个页面,为了实现代码复用,这里定义一个专门的下载函数,这个下载函数主要就是使用 Requests 下载页面,并返回一个页面信息提取器。
def download(url):
html = requests.get(url, headers=headers)
time.sleep(2)
return etree.HTML(html.text)其次,定义保存函数。
def data_writer(item):
with open('qfang_ershoufang.csv', 'a',
encoding='utf-8', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerow(item) 下面定义最主要的爬取函数,它能从房源列表页面中解析出房源详情页的 URL,然后打开这个 URL,从中提取出房源年限信息和抵押信息。
def spider(list_url):
selector = download(list_url) #下载列表页
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]
#构造详情页 URL
house_url = ('http://shenzhen.qfang.com'
+ house.xpath("div[1]/p[1]/a/@href")[0])
sel = download(house_url) #下载详情页
time.sleep(1)
house_years = sel.xpath("//div[@class='housing-info']/ul"
"/li[2]/div/ul/li[3]/div/text()")[0]
mortgage_info = sel.xpath("//div[@class='housing-info']/ul"
"/li[2]/div/ul/li[5]/div/text()")[0]
item = [apartment, house_layout, area, region,
total_price, house_years, mortgage_info]
print('正在抓取', apartment) #显示抓取的信息
data_writer(item) 上面的代码提取出房源详情页面网址 house_url,继续使用 download 函数下载这个页面,然后在返回的选择器 sel 上使用 XPath 语法提取数据。
最后,定义主函数。这次我们爬取 10 个列表页面。
if __name__ == '__main__':
for x in range(1 , 11):
spider(pre_url + str(x))这样就完成了整个爬虫的编写。读者可以在 PyCharm 中运行并看到爬取的数据,如图 4-6 所示。

图 4-6 代码在 PyCharm 中的运行结果
这里对使用 XPath 做一个小的总结,以供读者参考。
一是用户既可以直接从 Chrome 浏览器中复制 XPath,也可以自己根据 HTML 代码的特点来写。例如编写上面提取房源年限信息的 XPath 路径时,如果直接复制 Chrome 浏览器中的 XPath,应编写如下代码。
//*[@id="scrollto-1"]/div[2]/ul/li[2]/div/ul/li[3]/div
这里编写的 XPath 路径如下。
//div[@class='housing-info']/ul/li[2]/div/ul/li[3]/div
可以看出,两者的效果是完全相同的。
二是在写 XPath 路径时,充分利用页面的源码,能确定某些元素的唯一性。例如在上面写的 XPath 路径中,读者可能会怀疑 class 属性等于 housing-info 的<div>标签是否是唯一的,这时可以在房源详情页空白处单击右键,在弹出的菜单中选择“查看网页源码”,然后在打开的网页源码页面中搜索 class="housing-info"。如果发现只有一条匹配结果,就可以确定使用从根目录查找//div[@class='housing-info']是没有问题的。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论