【爬虫学习四】 Python大型爬虫案例: 抓取某电商网站的商品数据 (1)
目标:获取整个“*行”的产品列表
需要用到的链接和网站:
电商网站:https://www.qunar.com/
在线编码转换:https://tool.oschina.net/encode?type=4
以下为观察解析数据得出的链接(第一部分内容):
出发地对应的目的地: https://touch.dujia.qunar.com/golfz/sight/arriveRecommenddep=%E5%8C%97%E4%BA%AC&exclude=&extensionImg=255,175
出发点列表的链接:https://touch.dujia.qunar.com/depCities.qunar
出发点到目的地的产品:
https://touch.dujia.qunar.com/list?modules=list%2CbookingInfo%2CactivityDetail&dep=%E5%8C%97%E4%BA%AC&query=%E4%B8%89%E4%BA%9A%E8%87%AA%E7%94%B1%E8%A1%8C&dappDealTrace=true&mobFunction=%E6%89%A9%E5%B1%95%E8%87%AA%E7%94%B1%E8%A1%8C&cfrom=zyx&it=dujia_hy_destination&date=&needNoResult=true&originalquery=%E4%B8%89%E4%BA%9A%E8%87%AA%E7%94%B1%E8%A1%8C&width=480&height=320&quality=90&limit=0,20&includeAD=true&qsact=search&filterTagPlatform=mobile_touch
一:观察页面特征和解析数据
浏览器中访问:https://www.qunar.com/
按 F12 进入开发者模式
然后按 ctrl + shift + m(或者点图中圈红)
现在就进入了无线端模式,无线端返回数据为JSON格式,更加容易处理。
(1) 点击“*行”后,然后点击搜索框,就可以观察到树状结构,如下图
(2) 切换为 Header 页面,有两条重要信息(圈红部分)
Request URL (请求链接) :通过链接访问服务器获取数据
Request Method (请求方法) :决定使用的函数方法和上传参数,常见的请求方法有 GET 和 POST 方法。
其中:
GET方法只有查询数据的权限,只要访问URL就可以返回数据;
POST方法需要权限验证和请求内容,服务器通过权限放行,通过请求内容返回客户端请求的数据,POST方法具有查询和修改数据的权限。
可以得出:
Request URL (请求链接) 删掉后面的callback :https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep=%E5%8C%97%E4%BA%AC&exclude=&extensionImg=255,175
Request Method (请求方法) : GET方法
(3) 随便点击一个推荐的城市 (此处点了三亚)
观察 Request URL , 链接中%开头的字符串是中文编译的字符串,服务器无法识别中文字符,所以是以某种编码方式编译后才能提交到服务器。
打开 在线编码转换 进行解码
https://touch.dujia.qunar.com/list?modules=list%2CbookingInfo%2CactivityDetail&dep=%E5%8C%97%E4%BA%AC&query=%E4%B8%89%E4%BA%9A%E8%87%AA%E7%94%B1%E8%A1%8C&dappDealTrace=true&mobFunction=%E6%89%A9%E5%B1%95%E8%87%AA%E7%94%B1%E8%A1%8C&cfrom=zyx&it=dujia_hy_destination&date=&needNoResult=true&originalquery=%E4%B8%89%E4%BA%9A%E8%87%AA%E7%94%B1%E8%A1%8C&width=480&height=320&quality=90&limit=0,20&includeAD=true&qsact=search&filterTagPlatform=mobile_touch
解码后的链接,与浏览页面对比可以发现
dep = 北京 (出发地)
query = 三亚*行 (目的地)
originalquery = 三亚*行 (目的地)
(4) 想获得所有“*行”产品,就要先获取所有出发点,因为从不同的城市出发,会有不同的产品。
选择出发地:
找到出发地列表
获取出发点列表的链接:
https://touch.dujia.qunar.com/depCities.qunar
二 : 工作流程分析
(1) 获取出发点列表
(2) 获取旅游景点列表
(3) 获取经典产品列表
(4) 存储数据
三: 构建类目树
(1)获取出发点列表
树状结构:
import requests
url = 'https://touch.dujia.qunar.com/depCities.qunar' #出发点列表的链接
str = requests.get(url)
dep_dic = str.json()
for dep_item in dep_dic["data"]:
for dep in dep_dic["data"][dep_item]:
print(dep)
运行结果:
(2) 获取旅游景点列表
根据出发地获得目的地,继续输入代码。
树状结构:
import requests
import time
url = 'https://touch.dujia.qunar.com/depCities.qunar' #出发点列表的链接
str = requests.get(url)
dep_dic = str.json()
for dep_item in dep_dic["data"]:
for dep in dep_dic["data"][dep_item]:
print(dep)
#新加入的代码
url = 'https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep={}&exclude=&extensionImg=255,175'.format(dep)
time.sleep(1)
str = requests.get(url)
arrive_dic = str.json()
arrive_city = [] #存放当前出发点能到的所有目的地
for arr_item in arrive_dic["data"]:
for arr_item_1 in arr_item["subModules"]:
for query in arr_item_1["items"]:
if query["query"] not in arrive_city: #使得当前出发点对应的目的地不重复
arrive_city.append(query["query"])
print(arrive_city)
运行结果:
四: 获取产品列表
import requests
import time
import pymongo
client = pymongo.MongoClient('localhost',27017) #建立连接
book_qunar = client['qunar'] #建立名为“qunar” 的数据库
sheet_qunar = book_qunar['sheet_qunar'] #在数据库中创建新表 “sheet_qunar”
url = 'https://touch.dujia.qunar.com/depCities.qunar' #出发点列表的链接
str = requests.get(url)
dep_dic = str.json()
for dep_item in dep_dic["data"]:
for dep in dep_dic["data"][dep_item]:
print(dep)
url = 'https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep={}&exclude=&extensionImg=255,175'.format(dep)
time.sleep(1)
str = requests.get(url)
arrive_dic = str.json()
arrive_city = [] #存放当前出发点能到的所有目的地
for arr_item in arrive_dic["data"]:
for arr_item_1 in arr_item["subModules"]:
for query in arr_item_1["items"]:
if query["query"] not in arrive_city: #使得当前出发点对应的目的地不重复
arrive_city.append(query["query"])
for item in arrive_city:
url = 'https://touch.dujia.qunar.com/' \
'list?modules=list%2CbookingInfo%2' \
'CactivityDetail&dep={}&query={}&' \
'dappDealTrace=true&mobFunction=%E' \
'6%89%A9%E5%B1%95%E8%87%AA%E7%94%B1' \
'%E8%A1%8C&cfrom=zyx&it=dujia_hy_dest' \
'ination&date=&needNoResult=true&origina' \
'lquery={}&width=480&height' \
'=320&quality=90&limit=0,' \
'20&includeAD=true&qsact=search&' \
'filterTagPlatform=mobile_touch'.format(dep,item,item)
time.sleep(1)
str = requests.get(url)
routeCount = int(str.json()["data"]["limit"]["routeCount"]) #取出产品数
for limit in range(0,routeCount,20): #获取产品信息
url = 'https://touch.dujia.qunar.com/' \
'list?modules=list%2CbookingInfo%2' \
'CactivityDetail&dep={}&query={}&' \
'dappDealTrace=true&mobFunction=%E' \
'6%89%A9%E5%B1%95%E8%87%AA%E7%94%B1' \
'%E8%A1%8C&cfrom=zyx&it=dujia_hy_dest' \
'ination&date=&needNoResult=true&origina' \
'lquery={}&width=480&height' \
'=320&quality=90&limit={},' \
'20&includeAD=true&qsact=search&' \
'filterTagPlatform=mobile_touch'.format(dep,item,item,limit)
time.sleep(1)
str = requests.get(url)
#产品的数据类型
result = {
'date': time.strftime('%Y-%m-%d',time.localtime(time.time())),
'dep': dep,
'arrive': item,
'limit': limit,
'result': str.json()
}
sheet_qunar.insert_one(result)
运行结果: