爬完木鸟短租后开始攻克小猪。小猪的网页结构和木鸟很像,我写的爬取
计划和学习点是:
1.城市数目封装函数
2.获得城市列表
3.在城市列表循环,爬取城市数目
4.写入excel表。
第一步进行的很顺利,按部就班的用chrome在小猪这里找到单个城市的房源数,copy xpath得到链接。小猪的房源数没有木鸟的准确,不过也算数吧。
但在城市列表这里就遇到坑了。小猪的城市列表不算难找(前提是你知道在JS找的话),但是xz.citys就是一个list,还真不知道怎么用json取。
yaung说直接copy过来,然后调用就好了。我觉得这样很搬砖,但是大神说,请求加解析也是很耗费资源的。
好吧,然后程序里就有了一百多行的一个list表。贡献了整个程序体积的3/4。当然这里可以写成一个模块调用,不过我还没有练习。
然后每一行是一个城市也是一个循环,在循环里直接a=city[x]这样调用就好了。
到了这步终于把整个代码写好了,但是运行报错。我看了又看觉得问题还是在于函数不熟,前面定义的函数后面调用的不对。虽然知道错在哪里但是改来改去,连全局变量global都用上了。
自己又垂死挣扎了了大半个小时后让yaung看看,大神用了8分钟就改完了,真是小泪心酸啊~拿到之后对比一下,还好,主要就是改了三个地方:
- 定义链接这里,没有写format,表达不完整。
url = 'http://{city_temp}.xiaozhu.com/?startDate=2017-06-06&endDate=2017-06-08'.format(city_temp=city_temp)
- 因为有运用模块(我的理解是前面的函数),所以要加上这个语句,先写下这个条件语句再开始城市列表循环。
if __name__ == '__main__':
3.将先前定义的函数,所取得的城市房间数 赋予新的变量city_number,
在我的原稿中就是get_city_room_num(city_code),最先报错也是这里。大概最严重的错误也是这里。(比起上次连个json都看不懂,这时候感觉已经进步了...)
city_number = get_city_room_num(city_code)
然后就运行出来了!拿到结果一看,很多很奇怪的数据,比如兴安这个我都搞不懂在哪个省的地方,居然有3000+房源。然后也有很多城市的数据是空白的。再尝试了几下,原来虽然城市列表的拼音缩略和实际找房的url不一样。
比如xa在城市列表中是兴安,但xa.xiaozhu.com就代表了西安,所以房源才那么多。
写程序的人思路系这样:你搜索“杭州”,城市列表指向hz,但是实际的url可以是hz.xiaozhu.com,也可以是hangzhou.xiaozhu.com。然后还有些例外,比如兴安/西安这个。
又试了一下,用城市全拼也是可以找到链接的,比如xian.xiaozhu.com就肯定不会错。
所以在城市循环中,把city_code从city[0]改为[2],再带入url中,爬到的数据就正确多了。
完整代码如下:
# coding:utf-8
import random
import requests
from lxml import etree
def getReqHeaders(): # 功能:随机获取HTTP_User_Agent
user_agents = ["Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"]
user_agent = random.choice(user_agents)
req_headers = {'User-Agent': user_agent}
return req_headers
def get_city_room_num(city_temp):
url = 'http://{city_temp}.xiaozhu.com/?startDate=2017-06-06&endDate=2017-06-08'.format(city_temp=city_temp)
html = requests.get(url, headers=getReqHeaders()).content
selector = etree.HTML(html)
return selector.xpath('//*[@id="searchTotal"]/text()')
#copy city_list
city_list = [["bj", "北京", "beijing", "bj", "2079", "beijing", "北京", "", "", 12],
["sh", "上海", "shanghai", "sh", "910", "shanghai", "上海", "", "", 13]]#以下略
city_dict = []
if __name__ == '__main__':
for city in city_list:
item = {}
city_code = city[2]
city_name = city[1]
city_number = get_city_room_num(city_code)
item['city'] = city_code
item['city_name'] = city_name
item['number'] = city_number
# item['province']=province
city_dict.append(item)
print(item)