通过滚动的高度来判断是否到达了底部
无限滚动的逻辑原理
无限滚动的逻辑原理主要是,通过滚动的高度来判断是否到达了底部,如果到达了底部就不滚动,否则就可以滚动。
“滚动”时,通过判断上一页查看的最后一条记录的ID,通过最后一条记录ID来获取新的一页的数据,从而实现无限滚动的分页。
我们以微博为例,微博的滚动逻辑是这样的:
- 初始化时,获取第一页的数据,并保存到本地。
完整的请求链接是:https://weibo.com/ajax/statuses/mymblog?uid=微博用户的ID&page=1&feature=0,
加入请求的数据最后一条ID=1024
- 滑动到了当前数据底部,就可以继续请求数据并滚动了:
则第二次完整的请求链接为:https://weibo.com/ajax/statuses/mymblog?uid=微博用户的ID&page=2&feature=0&since_id1024
这里我并不清楚其中的feature含义是什么,我们也并不关心。
知道了无限滚动的实现原理,我们就可以想办法来模拟滚动,从而实现完整数据的下载了。
如何使用Python下载图片
首先,我们来看看,如何使用Python根据一个图片的网上链接下载图片。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import requests import requests import os
imgUrl = 'https://wx2.sinaimg.cn/large/005yvl0gly1guqphioirnj60x21ml7hm02.jpg'
path = 'D:\\xxx\\xxxx\\xxx' img = path + '\\' + os.path.basename(imgUrl) try: if not os.path.exists(path): os.makedirs(path) else: r = requests.get(imgUrl) with open(img, 'wb') as f: f.write(r.content) except: print('下载失败')
|
模拟Http请求
基于无限滚动的方式就需要我们自己来模拟接口请求,并处理返回的数据。
注意,需要请求时需要携带Cookies,否则一般情况下会被网站拒绝。
1 2 3 4 5 6 7 8
| import requests
cookie = '个人cookies' headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36', 'Cookie': cookie}
url = '请求地址' data = requests.get(url, headers=headers) print(data.content)
|
解析数据
多数情况下返回的数据为json字符串,在python中,请求的数据格式大多数为bytes,所以需要解码成字符串,然后转换成json格式。
即bytes -> str -> json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import json import requests
url = '请求地址' data = requests.get(url, headers=headers)
content = str(data.content, encoding='utf-8')
json_data = json.loads(content)
print(json_data['data'])
for key, v in pic_infos.items(): print(key) print(v)
|
完整的爬虫示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| import requests import json import os
uid = '微博用户的ID' downloadPath = 'D:\\xxx\\xxx' cookie = '你的cookie' headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36', 'Cookie': cookie}
def downloadPic(url, path): img = path + '\\' + os.path.basename(url) try: if not os.path.exists(path): os.makedirs(path) else: r = requests.get(url) with open(img, 'wb') as f: f.write(r.content) except: print('下载失败')
notEnd = True page = 1 since_id = '' while notEnd: print('当前页数:', page) url = 'https://weibo.com/ajax/statuses/mymblog?uid=' + uid+ '&feature=0&since_id=' + since_id +'&page=' + str(page) data = requests.get(url, headers=headers) content = str(data.content, encoding='utf-8') c = json.loads(content) list = c['data']['list'] last_item = '' if len(list) > 0: for item in list: last_item = item nickname = item['user']['screen_name'] for key, value in item.items(): if key == 'pic_infos': pic_infos = value for pic_infoKey, pic_info in pic_infos.items(): pic = pic_info['original'] downloadPic(pic['url'], path=downloadPath + '\\' + nickname) page = page + 1 since_id = str(last_item['id']) + 'kp' + str(page)
|
在实际运行过程中,发现除了对应用户外,还会下载一些其他内容,比如他点赞的一些微博也会在其中出现。可以不用管他,也可以通过判断用户id将其过滤掉。
最后
本文仅做技术讨论,仅支持获取公开数据,遵守中国法律法规!
爬虫有风险,爬取需谨慎!如违规,请自行承担,别找我啊!