您的位置:首页 > 编程语言 > Python开发

Python3爬虫(2)xpath模块代替re正则模块的使用

2018-04-02 20:31 686 查看
前言

最近学习了一下python3.5中爬虫的原理套路!

之前写demo的时候,获取html源码后一直在使用python自带的re模块来用正则表达式匹配数据。

不得不说!正则很强大!(强大的.*?,笑),各种复杂的情况下都可以匹配的到,但是写法非常灵活,每个人的思维模式不一样,写出来也就不一样,对于没有接触过正则表达的同学来说,学习成本还是需要一写的!

所以今天来说一下对于我这种正则小白的福音!python下提供的一个基于正则的模块,xpath,使用节点的概念来匹配你所获取到的页面源码!超级好用!

[xpath菜鸟教程学习传送门]:点击打开链接

今天用xpath写了一发get 58同城租房信息的demo,下面附上流程和code

A.实现思路

58同城首页->租房->北京出租

首先我们得到的是一个这样的页面



点进去之后得到这样一个页面



那么我们爬取信息的套路就可以初步确定下来了!

1.首先在房源信息列表页面循环分页获取到每篇独立的房源帖子url,也就是a标签中的href。

2.接着我们需要循环向这些帖子的url发起网络请求(使用requests模块或自带urllib模块都可以啦~)获取每篇帖子的html源码

3.获取每篇帖子的源码后!我们就可以分析源码的结构,然后使用xpath(代码中实际引用的是lxml这个文件)进行匹配数据,获取到我们需要的信息了!

4.获取每个房源的信息,并把图片都存储下来!

B.获取到的数据

1.房源json信息



2.房源图片的存储



C.实现代码

from urllib import request
#lxml就是xpath的模块
from lxml import etree
import requests,json,time

#爬取一级列表网页信息
def get_pages(page_num):
#确认目标
target = 'http://bj.58.com/chuzu/?PGTID=0d3090a7-0000-1299-6863-0094cd8364e7&ClickID={}'.format(page_num)
#发起网络请求
response = requests.get(target)
response.encoding = 'utf-8'
#获取html源码
html = response.text

#使用lxml进行数据匹配
html = etree.HTML(html)

#获取房源信息,进入单个帖子的url
url_lists = html.xpath('//div[@class="listBox"]//h2//@href')

for url in url_lists:
get_page_info(url)
time.sleep(2)

#爬取二级详情页面信息
def get_page_info(url):
response = requests.get(url)
response.encoding = 'utf-8'
page_code = response.text

#储存房源信息dict house_info
house_info = {}
html = etree.HTML(page_code)

#房源信息标题
title = html.xpath('//div[@class="house-title"]/h1/text()')
if title:
house_info['title'] = title[0]
#月租
pay_month = html.xpath('//div[@class="house-pay-way f16"]//b/text()')
if pay_month:
house_info['pay_month'] = pay_month[0]
#租赁方式
pay_type = html.xpath('//ul[@class="f14"]/li[1]/span[2]/text()')
if pay_type:
house_info['pay_type'] = pay_type[0]
#房屋类型
house_type = html.xpath('//ul[@class="f14"]/li[2]/span[2]/text()')
if house_type:
house_info['house_type'] = house_type[0].strip()
#朝向楼层
house_dxnb = html.xpath('//ul[@class="f14"]/li[3]/span[2]/text()')
if house_dxnb:
house_info['house_dxnb'] = house_dxnb[0]
#所属区域
house_location = html.xpath('//ul[@class="f14"]/li[4]/span[2]/text()')
if house_location:
house_info['house_location'] = house_location[0]
#详细地址
house_adress = html.xpath('//ul[@class="f14"]/li[6]/span[2]/text()')
if house_adress:
house_info['house_adress'] = house_adress[0].strip()
#销售员名称
agent_name = html.xpath('//p[@class="agent-name f16 pr"]//text()')
if agent_name:
house_info['agent_name'] = agent_name[0].strip()
#销售员电话
agent_phone = html.xpath('//span[@class="house-chat-txt"]/text()')
if agent_phone:
house_info['agent_phone'] = agent_phone[0]
#房屋特点
house_special = html.xpath('//ul[@class="introduce-item"]/li[1]//span[2]/em/text()')
if house_special:
house_info['house_special'] = house_special
#房源描述
house_des = html.xpath('//ul[@class="introduce-item"]/li[2]//p/span/text()')
if house_des:
house_info['house_des'] = house_des
#房屋描述图片
pic_urls = html.xpath('//ul[@id="housePicList"]/li/img/@lazy_src')

#循环截取出图片的名称
img_list = []
for url in pic_urls:
first_url = url.split('?')
pic_name = first_url[0].split('/')[-1] + '.jpg'
img_list.append(pic_name)

#图片名称存入house_info中
house_info['house_imgs'] = img_list

#下载图片
request.urlretrieve(url,'./images/'+ pic_name)

with open('./house.json','a',encoding='utf-8') as f:
#json.dumps()-> dict转json
f.write(json.dumps(house_info,ensure_ascii=False) + '\n')

#打印结果
print(house_info)

if __name__ == '__main__':
#循环页数
for page_num in range(1,2):
get_pages(page_num)


D.注意事项

1.demo中只爬取了一页的房源信息,如需更改请修改主进程中的for in循环range值

2.如果有使用fiddler或者Charless这样抓包工具的同学,在跑demo的时候请先关闭一下,否则会报一个http error 504的错误

[http error 504 大神错误解决方案传送门]:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  爬虫 xpath python3