代理的使用

我们在做爬虫的过程中经常会遇到这样的情况:最初爬虫正常运行,正常抓取数据, 一切看起来都是那么好,然而 一杯茶的功夫可能就会出现错误,比如 403 Forbidden ;这时候网页上可能会出现“您的 IP 访问频率太高”这样的提示,或者跳出一个验证码让我们输入,之后才可能解封,但是一会之后又出现这种情况。

出现这个现象的原因是网站采取了一些反爬虫的措施。比如,服务器会检测某个 IP 在单位时间内的请求次数,如果超过了某个阈值,那么服务器会直接拒绝服务,返回一些错误信息。这种情况可以称为封 IP ,于是乎网站就成功把我们的爬虫禁掉。

代理的设置

之前介绍了多种请求库,如 requests、urllib、selenium 等。接下来我们来了解一下具体的代理如何使用,首先,我们来梳理一下这些请求库的代理设置方法。

获取代理

在测试之前,我们需要先获取一个可用代理,搜索引擎搜索“代理”关键字,就可以看到许多代理服务网站,网站上会有很多免费代理。但是免费代理大多情况下都是不好用的,所以比较靠谱的方法是购买付费代理。付费代理在很多网站上都有售卖,数量不用多,稳定可用即可,我们可以自行选购。

如果本机有相关代理软件的话,软件一般会在本机创建 HTTP 或 SOCKS 代理服务,本机直接使用此代理也可以。

在这里,我将使用代理:49.82.61.160:9999 来演示代理设置方法,设置代理测试的网址是 http://httpbin.org/get,我们访问该网址可以得到请求的相应信息,其中 origin 字段就是客户端的 IP,我们可以根据它来判断代理是否设置成功。

urllib 代理设置

首先,我们以最基础的 urllib 为例,来看一下代理的设置方法,在这里我们需要使用 ProxyHandler 处理器来设置代理,代码如下所示:

from urllib.request import ProxyHandler,build_opener

proxy = '49.82.61.160:9999'
proxy_handler = ProxyHandler({
    'http':'http://' + proxy,
    'https':'https://' + proxy
})
opener = build_opener(proxy_handler)
try:
    response = opener.open('http://httpbin.org/get')
    print(response.read().decode('utf-8'))
except:
    print('Error')

运行结果如下:

{
  "args": {},
  "headers": {
    "Accept-Encoding": "identity",
    "Cache-Control": "max-age=259200",
    "Host": "httpbin.org",
    "User-Agent": "Python-urllib/3.6",
    "X-Amzn-Trace-Id": "Root=1-609659c7-5aee471052c6eba962d30014"
  },
  "origin": "49.82.61.160",
  "url": "http://httpbin.org/get"
}

在这里,我们使用了 ProxyHandler 来设置代理,其参数是字典类型,键名为协议类型,键值是代理。注意,此处代理前面需要加上协议类型,即 http 或者 https。

创建完 ProxyHandler 对象后,我们需要利用 build_opener() 重新构造 Opener,此时相当于此 Opener 已经设置好了代理。接下来直接调用 open() 方法,即可访问我们想要的链接。

运行输出结果是一个 JSON ,它有一个字段 origin ,标明了客户端的 IP。验证一下,此处的 IP 确实为代理的 lP ,并不是真实的 IP 。这样我们就成功设置好代理,并可以隐藏真实 IP 了。

如果遇到需要认证的代理,我们可以用以下方法设置:

proxy = 'username:password@49.82.61.160:9999'

这里改变的只是 proxy 变量,我们只需要在代理前面加入代理认证的用户名密码即可。

requests 代理设置

对于 requests 来说,代理设置更加简单,我们只需要传入 proxies 参数即可。

还是以上面的代理为例,我们来看一看 requests 的代理设置:

import requests

proxy = '49.82.61.160:9999'
proxies = {
    'http':'http://' + proxy,
    'https':'https://' + proxy
}
try:
    response = requests.get('http://httpbin.org/get',proxies=proxies)
    print(response.text)
except:
    print('Error')

运行结果如下:

{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Cache-Control": "max-age=259200",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.22.0",
    "X-Amzn-Trace-Id": "Root=1-60966030-6bc9361f662606ca41350d91"
  },
  "origin": "49.82.61.160",
  "url": "http://httpbin.org/get"
}

可以发现,requests 的代理设置比 urllib 简单得多,它只需要构造代理字典,然后通过 proxies 参数传递即可。

其运行结果的 origin 也是代理的 IP ,这证明代理已经设置成功。如果代理需要认证,同样在代理的前面加上用户名密码即可,代理的写法就变成如下所示:

proxy = 'username:password@49.82.61.160:9999'
Selenium 设置代理

Selenium 同样可以设置代理,在此,我们以有界面浏览器 Chrome 为例来展示代理设置:

from selenium import webdriver

proxy = '49.82.61.160:9999'
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--proxy-server=http://' + proxy)
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get('http://httpbin.org/get')
print(driver.page_source)

在这里我们通过 ChromeOptions 来设置代理,在创建 Chrome 对象时用 chrome_options 参数传递即可。

运行代码之后便会弹出一个 Chrome 浏览器,我们访问目标链接之后输出结果如下所示:

{  "args": {},
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
    "Accept-Encoding": "gzip, deflate",
    "Accept-Language": "zh-CN,zh;q=0.9",
    "Cache-Control": "max-age=259200",
    "Host": "httpbin.org",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
    "X-Amzn-Trace-Id": "Root=1-6096628a-2de37be2136f86544f5001bd"
  },
  "origin": "49.82.61.160",
  "url": "http://httpbin.org/get"
}

对于无界面浏览器 PhantomJS 来说,代理设置方法可以借助 service_args 参数,也就是命令行参数。代理设置方法如下:

from selenium import webdriver

service_args = [
    '--proxy=49.82.61.160:9999',
    '--proxy-type=http'
]
driver = webdriver.PhantomJS(service_args=service_args)
driver.get('http://httpbin.org/get')
print(driver.page_source)

我们只需使用 service_args 参数,将命令行的一些参数定义为列表,在初始化的时候传递给 PhantomJS 对象即可。

代理池的维护

我们在上一节了解了利用代理可以解决目标网站封 IP 的问题。在网上有大量公开的免费代理,或者我们也可以购买付费的代理 ,但是代理不论是免费的还是付费的,都不能保证都是可用的,因为可能此 IP 被其他人使用来爬取同样的目标站点而被封禁,或者代理服务器突然发生故障或网络繁忙。一旦我们选用了一个不可用的代理,这势必会影响爬虫的工作效率。

所以,我们需要提前做筛选,将不可用的代理剔除掉,保留可用代理。接下来我们就搭建一个高效易用的代理池。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值