由于本人十一国庆想去成都旅游,所以这里就以成都这个城市的所有携程酒店为抓取的目标城市。想要抓取其他城市或者多个城市的博友们,可以更改url为其他城市拼音+城市id。或者直接将城市接口数据(js)爬取下来去遍历城市列表在循环页面。有兴趣的朋友可以去试试爬取全国的数据。
一、开始分析携程酒店页面数据结构及其反爬的一些方式
经过尝试一点下一页,发现页面url是没有变化的,将源码加载到本地,可以看到完整的url链接
所以直接在城市路由后边接着跟页码的路由路径就可以实现翻页的效果了
而且页面中的数据基本上可以拿到。除了酒店的价格信息是使用js动态加载的
在源码中可以找到动态加载的价格数据(酒店id:价格)
到时候只需要在酒店div数据下将酒店的id爬取下来,然后再将该数据取出来,转成字典。重构字典数据,格式为:酒店id数字:价格数字
二、进行页面请求,数据提取
这里数据提取,就不用了之前的xpath进行提取了。因为在网上看了一个新的解析库pyquery,所以就以此工具搭配requests工具进行页面请求和数据抓取。pyquery语法基于css语法。
数据提取代码如下:
import re
import json
import requests
from pyquery import PyQuery as pq
url = 'https://hotels.ctrip.com/hotel/chengdu28/p1'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36'
}
res = requests.get(url,headers=headers).content.decode('utf-8')
# with open('xiecheng.html','w',encoding='utf-8')as fp:
# fp.write(res)
# print(res)
# 使用pyquery加载HTML页面
html = pq(res)
# 抓取动态加载的价格数据
hllist = re.findall(r"htllist: '(.*?)',",res)[0]
# 将json格式字符串转为python类型 [{},{},...]
hllist = json.loads(hllist)
# 重新构建字典{’39341191‘:’299‘}
hotel_price = {
}
for i in hllist:
hotel_id = i['hotelid']
amount = i['amount']
hotel_price[hotel_id] = amount
print(hotel_price)
# 总页数
page_total = html('#txtpage').attr('data-pagecount')
print('总页数:',page_total)
# 取出酒店块列表,itmes方法返回的是一个生成器对象
items = html('#hotel_list > div > ul').items()
print(items)
i = 1
for ul in items:
# 酒店id,用去拿取动态渲染的数据,
hotel_id = ul.find('.hotel_pic a').attr('data-hotel')
print(hotel_id)
# 标题
print(i)
title = ul.find('.hotel_name > a').attr('title')
print(title)
# 地址
address = ul.find('.hotel_item_htladdress').text()
address = re.findall(r'(.*?)。 地图',address)[0]
print(address)
# 文字评分
score_text = ul.find('.hotel_level').text()
# 评分
score = ul.find('.hotel_value').text()
print(score_text,score)
# 用户推荐率
user_recommend = ul.find('.total_judgement_score').text().replace('用户推荐',''