在学习python爬虫的过程中,遇到各种反爬机制,个人总结了一下:
对同样的ip或User-Agent进行限制,
对频繁访问的ip进行限制,
设置登陆限制,
设置验证码,
设置Ajax加载页面。
目前小白我也就了解这么多,其中验证码的反反爬还在学习当中,学无止境啊
第一篇就说点简单的。
如果遇到前两种,还是比较好解决的。
遇到对User-Agent进行限制的,可以在代码中修改请求头,即
headers = {
"User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50"
}
写入Request中就可以了,推荐个网站,里面的常用的User-Agent比较全,提示!提示!提示!网站中的那一行行里面前面的user-agent是不需要的,只要后面的。
http://www.jsons.cn/useragent/
对于限制ip的,第一,可以自己整一个代理ip尝试,这种也是成功一时的方法,长久参考,设置一个代理池是比较妥当的方法。
在scrapy框架中,代理池可以设置在settings里面,也可以设置在 中间件Middlewares.py中,这里就说一下在中间件Middlewares
中设置代理池吧,上代码
# 首先,这是自己能够找到ip的时候,可以整个列表,然后写个随机函数随机取一个
import random
PROXIES = ['http://183.207.95.27:80', 'http://111.6.100.99:80']
class ProxyMiddleware(object):
'''
设置Proxy
'''
def process_request(self, request, spider):
ip = random.choice(PROXIES)
request.meta['proxy'] = ip
# 还有就是可以去一些专门做代理服务的网站购买代理池,我是在阿布云上购买的,
import base64
proxyServer = "http://proxy.abuyun.com:9020"
#new
proxyUser = "***************" #购买之后给的秘钥输入进去
proxyPass = "***************"
proxyAuth = "Basic " + str(base64.encodebytes(bytes(proxyUser + ":" + proxyPass, 'utf-8')), 'utf-8').strip()
class ProxyMiddleware(object):
def process_request(self, request, spider):
print("=============abuyun ==============", request.url)
request.meta["proxy"] = proxyServer
request.headers["Proxy-Authorization"] = proxyAuth
在这里补全一个使用自己爬取到的一些代理做的ip池,可以循环的取出准备的ip,并且把不能用的ip删除掉。
# ip代理
class ProxyMiddleware(object):
def __init__(self):
self.ip_pool = self.get_ip()
def get_ip(self):
return [
'182.18.6.9:53281',
'118.212.95.34:53281',
'114.91.164.97:9999',
'222.170.0.102:53281',
'120.92.74.189:3128',
'183.129.207.73:14823',
'124.204.78.12:8123',
]
def process_request(self, request, spider):
# 随机一个代理
self.ip = random.choice(self.ip_pool)
print('*' * 100)
print('现在使用的代理是--%s--' % self.ip)
print('*' * 100)
request.meta['proxy'] = 'http://' + self.ip
request.meta['download_timeout'] = 5
# 代理服务器连接失败,抛出异常,就会走这里
def process_exception(self, request, exception, spider):
print('*' * 100)
print(exception)
print('*' * 100)
# 干掉这个不可用的代理
self.ip_pool.remove(self.ip)
if len(self.ip_pool) < 2:
self.ip_pool = self.get_ip()
# 请求需要重写发送
return request