代理服务器:
在爬虫中,代理的主要作用是转发请求和接收响应的,防止短时间对服务器过度高频请求导致设备ip被禁。
代理服务器分类:
- 透明代理:应用服务器端知道你使用了代理机制,也知道你的真实ip
- 匿名代理:应用服务器端知道你使用了代理机制,不知道你的真实ip
- 高匿代理:应用服务器不知道你使用了代理机制,也不知道你的真实ip
我们在爬虫中并不是说一定要使用匿名代理,我们真正的目的是,通过代理ip来转发请求和接收数据,防止我们因高频访问应用服务器导致自身ip被封,无法爬取数据,我们更加倾向于使用高匿代理
代理类型:
- https类型的代理:只能转发https类型的请求
- http类型的代理:只能转发http类型的请求
- socket类型的代理:只能转发socket类型的请求
代理服务器推荐:
使用代理服务器
- 登录购买服务
- 添加ip白名单
- 提取API
基于代理精灵构建代理池代码
import requests
from lxml import etree
headers = {
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'
}
api_url = 'http://t.11jsq.com/index.php/api/entry?method=proxyServer.generate_api_url&packid=1&fa=0&fetch_key=&groupid=0&qty=3&time=1&pro=&city=&port=1&format=html&ss=5&css=&dt=1&specialTxt=3&specialJson=&usertype=15'
api_page_text = requests.get(url=api_url, headers=headers).text
tree = etree.HTML(api_page_text)
proxy_ip_list = tree.xpath('//body//text()') #取出的是一个代理服务器的ip列表,['60.184.255.56:34244', '115.53.130.139:32400', '114.101.23.12:15720']
#构建一个代理池
https_proxy_pool = []
for proxy in proxy_ip_list:
proxy_dic = {
'https': proxy
}
https_proxy_pool.append(proxy_dic) #https_proxy_pool为[{'https': '114.233.159.72:28803'},{'https': '183.94.12.188:25604'},{'https': '183.47.94.29:28803'}]
案例:使用代理服务器爬取西刺代理网站可用的高匿代理服务器的ip
- 练习链接
- 代码
import requests
from lxml import etree
import random
headers = {
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'
}
api_url = 'http://ip.11jsq.com/index.php/api/entry?method=proxyServer.generate_api_url&packid=1&fa=0&fetch_key=&groupid=0&qty=10&time=1&pro=&city=&port=1&format=html&ss=5&css=&dt=1&specialTxt=3&specialJson=&usertype=15'
api_page_text = requests.get(url=api_url, headers=headers).text
tree = etree.HTML(api_page_text)
proxy_pool_list = tree.xpath('//body//text()') #取出的是一个代理服务器的ip列表,['60.184.255.56:34244', '115.53.130.139:32400', '114.101.23.12:15720']
#构建一个字典类型的代理池,因为proxies参数值格式要求这样
https_proxy_pool = []
for proxy in proxy_pool_list:
proxy_dic = {
'https': 'https://' + proxy,
}
https_proxy_pool.append(proxy_dic) #https_proxy为[{'https': 'https://114.233.159.72:28803'},{'https': 'https://183.94.12.188:25604'},{'https': 'https://183.47.94.29:28803'}]
# https_proxy_pool
#使用代理服务爬取西刺网站的可用高匿ip
ips = []
base_url = 'https://www.xicidaili.com/nn/%d'
for page in range(1, 11):
url = format(base_url%page)
page_text = requests.get(url=url, headers=headers, proxies=random.choice(https_proxy_pool)).text #proxies参数值必须是字典类型,{'https':'ip:port'}
tree = etree.HTML(page_text)
#在xpath表达式中不能出现tbody标签,否则会导致xpath失效
tr_list = tree.xpath('//*[@id="ip_list"]//tr')[1:]
for tr in tr_list: #进行局部解析
ip = tr.xpath('./td[2]/text()')[0] #因为返回是一个列表,所以通过列表索引取出数据
ips.append(ip)
print(len(ips))
总结:
使用代理需要三步
- 获取代理服务器:从代理网站获取代理服务器的ip和端口,并封装成列表,列表值为一个一个
{'ip:port'}
的字符串 - 构建代理池:其实就是构建
'http': 'http://ip:port'
键值对类型的字典,作为代理池 - 传参:然后通过循环或者随机获取,从代理池中取出值,赋值给
requests.get(url=url, headers=headers, proxies=)
的proxies,其中赋给proxies的值必须是字典类型,且Python3.7之后格式必须为{'http': 'http://ip:port'}
,不能少了http://
或者https://
,否则会报错!!!