对于一些刚入行爬虫的小伙伴来说,刚开始的时候觉得所有的网站无非就是分析HTML、json数据,很容易忽忽略掉一个很重要的问题,那就是目标网站的反爬虫策略,很多目标网站为了反爬虫经常更新反爬策略,我们想要拿到数据,就需要针对它们的反爬虫来制定绕过方法,比如它识别你的UserAgent,那你可能就需要伪造、它限制IP请求次数,你可能就需要限速或者改变ip、它用验证码来识别你是人是机,你就需要模拟人的操作并且正确填写它给你弹出的验证码等等。
今天我们以实际项目举例:有个项目需要爬取拉勾网的数据,对方使用的反爬虫手段中除了上述的以外还需要进行登陆,很多信息都是需要登录以后才能爬取,关于登陆类的爬虫之前也分享了很多知识。这里就简单的过一下流程。
1、分析整个网页:首先需要获取到cookies,因为它是动态的,所以每隔一段时间都需要进行重新的获取
2、发送请求:当你获取到指定时间段的cookie之后,下一步要做的就是通过整个cookie和url放在一起朝服务器发送请求,获取到服务器发送出来的数据(得到之后需要使用json进行反序列化)
3、对当前页面数据中的内容进行指定的操作 如果你想要得到一大串数据中的指定的内容,那么你就可以通过一些第三方的类库来对这段数据进行操作
在此之前,我用过第三方库scrapy-proxys加上代理api接口,可能是之前代码没有调整好,导致的没有能够成功。所以这里直接使用亿牛云官方给出的python和scrapy的代码示例,
代码语言:javascript复制#! -*- encoding:utf-8 -*-
import requests
import random
# 要访问的目标页面
targetUrl = "http://httpbin.org/ip"
# 要访问的目标HTTPS页面
# targetUrl = "https://httpbin.org/ip"
# 代理服务器(产品官网 www.16yun.cn)
proxyHost = "t.16yun.cn"
proxyPort = "31111"
# 代理验证信息
proxyUser = "username"
proxyPass = "password"
proxyMeta = "http://%(user)s:%(pass)s@%(host)s:%(port)s" % {
"host" : proxyHost,
"port" : proxyPort,
"user" : proxyUser,
"pass" : proxyPass,
}
# 设置 http和https访问都是用HTTP代理
proxies = {
"http" : proxyMeta,
"https" : proxyMeta,
}
上面的是官方提供的python参考示例,下面还有官方提供的scrapy示例
代码语言:javascript复制 #! -*- encoding:utf-8 -*-
import base64
import sys
import random
PY3 = sys.version_info[0] >= 3
def base64ify(bytes_or_str):
if PY3 and isinstance(bytes_or_str, str):
input_bytes = bytes_or_str.encode('utf8')
else:
input_bytes = bytes_or_str
output_bytes = base64.urlsafe_b64encode(input_bytes)
if PY3:
return output_bytes.decode('ascii')
else:
return output_bytes
class ProxyMiddleware(object):
def process_request(self, request, spider):
# 代理服务器(产品官网 www.16yun.cn)
proxyHost = "t.16yun.cn"
proxyPort = "31111"
# 代理验证信息
proxyUser = "username"
proxyPass = "password"
# [版本>=2.6.2](https://docs.scrapy.org/en/latest/news.html?highlight=2.6.2#scrapy-2-6-2-2022-07-25)无需添加验证头,会自动在请求头中设置Proxy-Authorization
request.meta['proxy'] = "http://{0}:{1}@{2}:{3}".format(proxyUser,proxyPass,proxyHost,proxyPort)
# 版本<2.6.2 需要手动添加代理验证头
# request.meta['proxy'] = "http://{0}:{1}".format(proxyHost,proxyPort)
# request.headers['Proxy-Authorization'] = 'Basic ' base64ify(proxyUser ":" proxyPass)
# 设置IP切换头(根据需求)
# tunnel = random.randint(1,10000)
# request.headers['Proxy-Tunnel'] = str(tunnel)
# 每次访问后关闭TCP链接,强制每次访问切换IP
request.header['Connection'] = "Close"