在 Python 爬虫时,在一段时间内请求数量过多,有时由于防爬机制,可能会出现不能继续爬取的问题。解决问题的方法可以是加长请求的间隔,或者从根本上使用动态 IP ,即将大量请求分散到大量的 IP 地址上来请求,从而使防爬机制不会注意。
一个比较好用的高匿名 IP 的网站:
普遍的认识是这样的:
透明代理,即服务器知道请求方的代理 IP 和真实 IP
匿名代理,服务器知道使用了代理,但不知道真实的 IP
高匿代理,服务器不知道使用了代理,也就不会知道真实的 IP
其实使用高匿代理也只是增加了查询的难度,并不是查不到真实 IP 的。
对于爬虫的话,利用大量的高匿 IP ,并且加大请求间隔,是可以不被防爬机制注意的。
我们可以通过简单的代码来取到这个网站的所有 IP 地址来方便使用:
import requests import random import re url = /api/ html = requests.get(url=url, headers=headers).text regip = r<td>(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})</td>\s*?<td>(\d*)</td> matcher = re.compile(regip) ipstr = re.findall(matcher, html) ip_list = [] for ipport in ipstr: ip_list.append(ipport[0] + : + ipport[1]) # 随机获取列表中一个ip ip = random.choice(iplist)或者使用
from bs4 import BeautifulSoup; import requests import random url = /api/ html = requests.get(url=url, headers=headers).text soup = BeautifulSoup(html, lxml) ips = soup.find(id=ip_list).find_all(tr) ip_list = [] for i in range(1, len(ips)): ip_info = ips[i] tds = ip_info.find_all(td) ip_list.append(tds[1].text + : + tds[2].text) # 随机获取列表中一个ip ip = random.choice(iplist)使用时,可以使用 requests 来添加代理,获取响应:
response = requests.get(url, proxies={"http" : proxy}, timeout=10) return response.content或者使用 ProxyHandler :
httpproxy_handler = urllib.ProxyHandler({"http" : proxy}) opener = urllib.build_opener(httpproxy_handler) request = urllib.Request(image) opener.addheaders = headers; response = opener.open(request, timeout=10)另外,在使用动态 IP 的同时,可以使用动态 Header ,比如可以这样定好一个 header 的列表,每次请求 header 也随机取:
USER_AGENTS = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/ Firefox/61.0", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)", "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)", "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)", "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/ K-Ninja/2.1.1", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/ Firefox/3.0 Kapiko/3.0", "Mozilla/5.0 (X11; Linux i686; U;) Gecko/ Kazehakase/0.4.5"] headers = [(User-Agent, random.choice(USER_AGENTS)), ("Upgrade-Insecure-Requests", "1"), ("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"), ("Accept-Encoding", "gzip, deflate, sdch"), ("Accept-Language", "zh-CN,zh;q=0.8,en;q=0.6"), ("Cache-Control", "no-cache")]或者:
注意有时使用的组件不同header的写法格式也有区别
self.headers = {User-Agent: self.user_agent, "Upgrade-Insecure-Requests": "1", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6", "Cache-Control": "no-cache"}