背景
平时编写Blog的时候,使用了 sm.ms 的免费图床(┑( ̄。。 ̄)┍ 咳咳咳,这个名字不要误解,是一个正经的图片管理工具😂,如果访问流量比较少的,免费版本就可以满足需求), 后来想在本地也定时备份下所有的图片,以便后续更换图床做不时之需。 于是想到了爬虫去爬取已有的图片并下载到本地。
解决方案
最终通过调研,发现存在以下两种方式(欢迎提出其他解决方案):
方案一:BeautifulSoup 爬虫
优点:可指定获取特定页面的 HTML 内容,然后通过解析 HTML 内容来获取所有图片的信息。
缺点:每次需要去更新请求中的 Cookie 信息来爬取对应的页面内容。
优点:对外API接口中,/upload_history
接口返回了历史的上传记录,可以获取到所有的已上传的图片链接以及相关信息。
缺点:每次返回的是全量数据,这对于历史数据很多的用户,体验比较差。
遇到的问题
上面两种方案都试验过后实际都可以满足背景中的需求,但发现经过调试代码成功后,实际开始进行内容爬取的时候,直接请求报错。具体报错信息如下:
1
| RemoteDisconnected('Remote end closed connection without response')
|
┑( ̄。。 ̄)┍ oh,比较坏的情况发生了,可能由于请求过快被服务端给拉黑了。。。通过后面的实验发现应该是被服务端封了IP。
网上解决方案:使用User Agent和代理IP隐藏身份
但再使用网上的解决方案之前,存在一个比较怪异的现象,那就是同样的接口,使用本地的Postman却可以一直调用成功,使用本地的Pycharm脚本调用却一直失败。(都是通过API方式去调用的 /upload_history接口)
通过一系列的骚操作对比后,发现核心区别在于(postman自动使用了本地的代理端口去发送请求,也就是代理IP隐藏身份):
Python requests 解决该问题的核心代码如下:
1 2 3 4 5 6
| ...
proxy = {"http": "http://127.0.0.1:1235/", "https": "http://127.0.0.1:1235/"} res = requests.get(img_url, headers=headers, proxies=proxy, stream=True) with open(file_path, "wb") as f: f.write(res.content)
|
PS: 如何判断自己的代理生效了可参考如下代码(参考链接):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import requests from bs4 import BeautifulSoup
def validate(proxies=None): https_url = 'https://ip.cn/api/index?ip=&type=0' http_url = 'http://ip111.cn/' headers = {'User-Agent': 'curl/7.29.0'} https_r = requests.get(https_url, headers=headers, proxies=proxies, timeout=10) http_r = requests.get(http_url, headers=headers, proxies=proxies, timeout=10) soup = BeautifulSoup(http_r.content, 'html.parser') result = soup.find(class_='card-body').get_text().strip().split('''\n''')[0]
https_r_json = https_r.json() https_r_address, https_r_ip = https_r_json.get("address"), https_r_json.get("ip") with open("local_proxy.log", "a+") as f: f.write("=========================\n") f.write("访问https网站使用代理:%s %s\n" % (https_r_ip, https_r_address)) f.write("访问http网站使用代理:%s\n" % result)
|
1 2 3 4 5 6 7 8
| validate() >> 访问https网站使用代理:172.69.34.243 美国 加利福尼亚 >> 访问http网站使用代理:xxx.xxx.xx.xxx 中国 xx市
>> 访问https网站使用代理:153.122.116.100 日本 东京都 东京 >> 访问http网站使用代理:153.122.116.100 日本
|