概述
在面临一些爬虫爬取速度过快或者持续爬取的网站(一般都是大平台或者个别的敏感网站),那么你的爬虫极有可能会被封。就拿搜狗微信来说,这是个人真实面临的问题,最终通过一种方式解决了该问题。
搜狗微信的反爬虫主要是验证码,当你访问时间过快,那么你一定会被封的,因为就算你在浏览器一直点击刷新,你也会被封的。但是搜狗微信有两种封锁爬虫的机制。
第一,封cookie,当你在浏览器被封了之后,你只需要清空浏览器cookie就可以正常访问了。
第二,封IP,这个时候整个局域网的人都会被封。这是因为当你被封cookie之后,你还在持续请求该页面。
解决方案
针对上述两种封锁问题可以很明确的就是,只要cookie被封,我们立马停止该爬虫或者换上新的cookie就直接解决问题了。就不会引发第二种封锁。
面对第一种封锁,我们的解决思路如下,我们可以在数据库建立一个cookie池,里面持续加入cookie,当然这个获取cookie的爬取速度就可以放得很慢很慢。在爬虫里面,一旦给定的cookie被封,就从数据库拿出一条cookie出来继续爬虫。
本爬虫用的是scrapy爬虫,其他爬虫或框架的原理都是一样的。
核心代码如下:
class SpiderSpider(Spider.spider):
name = "spider"
allowed_domains = ["weixin.sogou.com"]
def __init__(self):
AllSpider.__init__(self)
# 实例化一个Cookiejar对象,这时候的cookiejar为空。
self.cookie_jar = CookieJar()
# 第一次给定的cookie,可以直接粘贴一个,也可以直接从数据库读取一个。
self.cookies = self.read_cookies()
def read_cookies(self):
Cookie = "SUID=34E5477D3220910A000000005B03C5B6; SUV=1526973879119417; LSTMV=238%2C304; LCLKINT=3091; sw_uuid=7254428489; weixinIndexVisited=1; CXID=38DEFD16444E743522E55C84A381BB20; ad=0kllllllll2bV6dAlllllVHVucUlllllKUKO2lllllyllllljZlll5@@@@@@@@@@; ABTEST=0|1531363605|v1; SUIR=8751F4CEB4B6DD84769A90F2B41B49FA; IPLOC=CN5101; JSESSIONID=aaaZq720YIbLH9UpL8Gsw; sct=35; PHPSESSID=qm5jharb5hcqlenc14755gsf95; SNUID=FA3795AFD2D6A3EFFC556385D3C48438; seccodeRight=success; successCount=1|Wed, 18 Jul 2018 02:59:49 GMT; refresh=1"
mycookie = {}
for cookiekv in Cookie.split(";"):
names, values = cookiekv.split("=", 1)
mycookie[names] = values
return mycookie
def start_request(self, response):
#这一步是请求的我们需要的页面
# 假定请求的连接是req_url
# 我们需要把这个连接传到下一个parse,因为如果被封了的话,我们可以重新获取cookie请求
time.sleep(random.randint(2,8))
# 这个地方的cookiejar还是一个空值,直到请求完这个链接才会填充。实际上就是我们粘贴的cookie。
yield scrapy.Request(req_url, callback=self.parse1,meta={"cookiejar":self.cookie_jar,"redirct_url":req_url},cookies=self.cookies ,dont_filter=True,method='get')
def parse1(self,response):
# 这个地方是判断这个爬虫已经被封,也就是说我们粘贴的cookie已经被封了,我们就需要重新获取cookie爬虫
Cookie:在数据库获取一个cookie
if response.status == 302:
time.sleep(random.randint(2, 8))
yield scrapy.Request(response.meta['redirct_url'], callback=self.parse1,meta={"cookiejar": self.cookie_jar, "originalUrl": response.meta['originalUrl']}, cookies=Cookie,dont_filter=True, method='get')
else:
pass
# 这个地方是我们加入了搜狗微信的搜索工具
query = re.findall('&query=(.*?)&',response.url)[0]
url = "http://weixin.sogou.com/weixin?type=2&ie=utf8&query={}&tsn=1&ft=&et=&interation=&wxid=&usip=&page=1".format(query)
time.sleep(random.randint(2, 8))
yield scrapy.Request(url,meta={'cookiejar': response.meta['cookiejar'], callback=self.parse3,dont_filter=True)
def parse3(self,response):
这个地方解析网页
说明:在scrapy中,cookieJar是可以自己维持cookie的,所以一般来说,只要访问不是太过于频繁,就不会出问题。因为,每一次的请求,就会得到一个响应cookie,这时候scrapy就会把这个响应cookie和请求的cookie共同维持下去,最终这个cookie请求多次时,很多参数已经和最初的cookie大相径庭了。
解决第二中封ip的问题。只需要在局域网内任意一台机器输入验证码就会解封,然后又可以重复上面第一种的思路继续爬虫。
总结
通过个人经验,其实我觉得爬虫最大的焦点就在于cookie,只要我们带了一个正确有效的cookie,就可以一直(正常)访问。包括封cookie,封ip,浏览器检查机制等,都可以通过从cookie的地方着手。就可以不必从验证码,代理ip的角度思考。只是在有些需要登陆的网站可能在获取cookie就会输入验证码,这个就不得不做验证码处理了。还有一些严重封ip的网站,或许会让你的ip在一段时间内都不能访问,这就需要你获取代理ip的手段来解决了。