爬虫06_基于代理服务器爬数据防止ip被封

代理服务器:

在爬虫中,代理的主要作用是转发请求和接收响应的,防止短时间对服务器过度高频请求导致设备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://,否则会报错!!!
发布了38 篇原创文章 · 获赞 43 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_40272386/article/details/105512208