您的位置:首页 > 其它

爬取自如租房多页信息

2019-07-13 12:37 99 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/Leon_Kbl/article/details/95734412

自如租房解决价格,解决价格与其他内容的融合。

爬取自如租房信息,我们很容易爬取到标题,房间大小等信息,但当我们获取价格时发现一个大坑,啥也不说,上图说话:

您瞧瞧,价格在标签内木有,木有啊!what*?%@*,但是通过分析你会发现它价格的几个数字的标签属性都一样,唯一的区别就是每张图backgraound-position参数不一样,同时对应的每个数字的参数也不一样。但是那又能咋样还是不知道神马东西!

然尔有问题就有解决的办法,我们在network中找到一个数字的图片。如下图:

那这图中的一串数字和价钱又有什么关系呢?
答案:‘有关系’,
该图片数字是:2710386495(0-9十个数字)
分析:
我们上图中得到的四个数字的background-position参数 -60,-240,-180,-90,这个正负号只是方向,相当于数学中的矢量,而我们需要只是值而已,而我们发现价钱的20*30的布局,当我们用四个参数除以宽度30会得到2863,而按它为下表索引取图片数字则取到的就是1960正好就是我们要的价格。

background-position/30=下标

同理,用同样的方法也可以取到第二张图的价格刚好就是2230,依此我们可以根据价格的间距去计算出下表再通过图片取出数字即为价格
所以我们的思路是:

1.找到这张含(0-9)的图片,并数字读取出来,
2.通过匹配取出移动距离,再通过计算得出下标,
3.通过下表取出价格

那么问题又来了,这张(0-9)的数字该如何找到,虽然整个请求中就这一张图,但是当你刷新时它就会发生变化,总不能手动取添加,这不符合一个爬虫工作者的身份,即使是个菜鸟,也觉得太low。

所以只要我们坚持不抛弃不放弃勇往直前的理念,希望还是有的,对于这些直接页面获取不到的东西,我们不妨去看看script里的内容,兴许就有惊喜。

上图说话:

我滴乖乖,图片链接竟然有,而且还有一堆列表数字,每个列表有四个数,而我们的价钱也是四个数,从数值上看,断定这不是价格,但上面分析来看,它会不会是取价格的下标呢!一对比,嘿,终于找到你,还好没放弃,幸福来之不易,才会让我倍加珍惜…,那这样图片链接和对应的价格下标都同时有了,那我们直接匹配出他俩,就算页面刷新,但他俩的变化是同步的,所以就你了,跑不了了。

下来的问题就是解决把图片里的数字提取出来,这里我们使用的超级鹰,这是一款收费的软解,但挺便宜的挺好用的。
这样图片里的数字也有了。
接下来就是取价格的思路整合一下:

1.找出图片地址和索引,用正则来匹配
2.通过图片地址找到图片用超级鹰解析出来数字
3.用下标取出价格

这样我们价格就得到了,但是这样就完成我们的任务了吗,没有,我们要爬取的不仅仅是价格,还有标题等内容,不是标题好爬吗?,好爬,但是和价格写一块又成了一个新的问题,他俩不是一个区域块爬取下来的内容,没办法直接按对应的房信息写到一个文件里面。
这里我们将获取价格写一个函数,标题写一个函数,各自返回结果为一个列表,然后使用zip()函数来讲二者融合,这样就构成一个块,可以对应内容写入文件了。

zip()函数:https://www.runoob.com/python/python-func-zip.html

废话不多说了,上代码解析:

请求
import requests
超级鹰导入 ,解析图片数字为字符串
import chaojiying
导入json
import json
导入正则
import re
导入bs4
from bs4 import BeautifulSoup

获取价格列表

def price(new_url,headers):
global req
res = requests.get(url=new_url, headers=headers)
res.encoding = res.apparent_encoding   编码
req = res.text
img_url=re.findall('"image":"(.*?)"',req)[0]   正则匹配出图片地址
new_url='http:'+img_url
img = requests.get(new_url)   访问图片地址
with open('code.jpg', 'wb') as f:
f.write(img.content)   保存图片
chaojiying2 = chaojiying.Chaojiying_Client('账号', '密码', '软件ID')
im = open('code.jpg', 'rb').read()   读出保存的图片
code = chaojiying2.PostPic(im, 1010)   1010代表超级鹰可以获取1~10位英文数字,
获取到图片内容的一个字典
index_list=re.findall('"offset":(.*])',req) 正则匹配出图片数字的下标列表
new_list=index_list[0]  str类型
alists=eval(new_list) eval转成列表类型 ,它是列表套列表
ziru_price = []
for i in alists:
astr = ""
for j in i:
price = (code['pic_str'][j])  j为列表的数字,也为图片字符串的下标,对应下标取出价格
astr += price 因为取出的价格是一个个字符串,所以进行拼接成一个完成的价格
ziru_price.append(astr) 得到一个价格列表
return ziru_price 这个函数最终返回价格列表

获取标题列表

def title():
global div_list  定义全局的bs4匹配的区域款,其他函数也可以使用
html = BeautifulSoup(req, 'lxml')
div_list = html.select('.txt')
title_list = []
for t in div_list:
title = t.select('h3 a')
#如果匹配到的是空的,就将它pass掉,防止取索引出错超出范围
if len(title) == 0:
pass
el
3ff7
se:
ziru_title = title[0].get_text()
title_list.append(ziru_title)  得到标题列表
return title_list 返回标题列表

获取面积列表

def spare():
spare_list = []
for s in div_list:   遍历title里定义好的全局区域块
spare = s.select('.detail p span')
#同理防止出超出索引的错误
if len(spare) == 0:
pass
else:
ziru_spare = spare[0].get_text()
spare_list.append(ziru_spare)  得到面积列表
return spare_list

整合三个列表进行写入到json

def write(ziru_title,ziru_price,ziru_spare): 按着实参顺序接收参数列表
zip_tuple=zip(ziru_title,ziru_price,ziru_spare) 将参数列表按顺序得到一个生成器
print(zip_tuple) ----><zip object at 0x00000274CB4A8B08>

list=[]
for ziru in zip_tuple:
#print(ziru) ----> ('友家 · 芭蕾雨悦都南区3居室-南卧', '1930', '11.5 ㎡')....
#ziru返回的是一个个元祖,通过下标来取出值,赋值给字典
item={}
item['title']=ziru[0]
item['price']=ziru[1]
item['spare']=ziru[2]
list.append(item)  通过下标取得的内容,依次写入字典
json.dump(list,open('ziru.json','a',encoding='utf-8'),ensure_ascii=False,indent=4)

程序入口

if __name__ == '__main__':
url = 'http://www.ziroom.com/z/nl/z3.html?p={}' 自如租房网
for i in range(1,11):
new_url=url.format(i)  循环拼接新地址,进行访问,爬取十页
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}
#自定义一个名字接收函数所对应返回的值,然后将这些值通过变量传参给写入文件的函数进行处理写入
ziru_price_list=price(new_url,headers)
ziru_title_list=title()
ziru_spare_list=spare()
write(ziru_title_list,ziru_price_list,ziru_spare_list)

菜鸟总结:

作为一个菜鸟新手,对于这样一个反爬就消耗了好多时间,但是从中页也拓展了思路,通过查询扩展了知识点,爬虫反爬的手段,我们就尝试模拟浏览器,拟到阿姨都认识它,那你就没有什么爬不到的了。总之就是想办法模拟,干就完了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: