关于爬虫学习的一些小小记录(五)——反爬与绕过

Python 爬虫 专栏收录该内容
7 篇文章 0 订阅

关于爬虫学习的一些小小记录(五)——反爬与绕过


前一篇给出了一种使用简单方法无法访问网页的情况,我们在这里对这种情况略作分析

尬聊

一般来说,在我们使用浏览器访问网站时,浏览器可以通过对数据的渲染呈现出更加友好的视觉效果。因为浏览器需要保证数据的渲染效果,不可能直接把未经处理的数据展现出来,这注定了我们很难通过浏览器实现大量、连续地获取内容数据。
但爬虫是可以直接获取内容和数据的,它不需要渲染的过程,就可以很轻松地抓取到大规模量集的数据。而且爬虫语法简单,极易上手,在这个数据爆炸的时代,爬虫就真的跟虫子一样,无处不在
相对的,万千爬虫过境,服务器要面临的压力成倍递增,维持服务器运转的成本也是直线上升。为了阻止爬虫对服务器无限制地索取数据,一系列的反爬虫手段被研发出来,一场爬虫与反爬的战争无限期展开……

反爬与反反爬

反爬技术,泛指那些为了限制爬虫而产生的互联网技术
反反爬技术,就是可以避开或绕过反爬技术的阻挡,成功爬取数据的技术

这里简单列举几种常见的反爬手段和相应的绕过反爬的方法,

登录验证,这个很常见,有些数据可能涉及个人隐私或者处于保密范围,需要验证用户身份才能开放访问。当然,也可能是为了阻挡爬虫这样的的非法访问者
绕过的方法也比较简单,使用浏览器保存的 cookie 进行验证,或者伪造 cookie 都可以避开

检查 User-Agent ,User-Agent 翻译过来就是用户代理,是 HTTP 请求的 headers 中用于认证终端身份的一个特殊字符串参数,记录了客户使用的操作系统版本、CPU 类型、浏览器的版本等信息。网站通过检查每个 HTTP 请求的 User-Agent 参数,判断发送请求的终端身份,从而把爬虫阻挡在外
只需要在访问网站时,把浏览器的 User-Agent 值填入自定义的请求头信息中(比如前一篇),再把头信息添加到 HTTP 请求一起发送给服务器,就能成功伪装浏览器访问

封 IP,当检查机制检测到某个 IP 段时间内高频次地请求网站,就会把该 IP 封锁,当然这是在 HTTP 请求不携带 cookie 的情况下。如果检测到携带 cookie,该反爬机制只会封禁 cookie,而不会封 IP
对于这样的反爬机制,我们可以使用代理 IP 来突破

url 重定向,这个跟封 IP 的机制有些类似,当反爬机制检测到某个 url 被连续高频率访问,就会将 url 重定向,使爬虫无法抓取到数据,同时会提示访问者登录。如果是登录情况下的连续请求,反爬机制会封锁 IP
可以通过伪造 cookie 和使用代理 IP 突破

设置验证码,这个不用多说,最常见的反爬手段之一,也很有效果
可以使用 OCR 识别验证码,进行突破

上面这些只是一些比较简单的手段,还有更高级的反爬技术这里就不列举了

简单点的例子

简单到只有一个代理 IP 的设置
先从西刺代理 (https://www.xicidaili.com/) 获取免费的代理 IP

省略分析网页源码的过程,代码如下

# 爬虫-- 获取代理 IP

from urllib import request
from bs4 import BeautifulSoup

url = 'https://www.xicidaili.com/wt/'  # 西刺代理,国内 HTTP 部分

req = request.Request(url)  # 访问网址
req.add_header('User-Agent',
	'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36')
page_info = request.urlopen(req).read().decode()

soup = BeautifulSoup(page_info, 'html.parser')

trs = soup.find_all('tr')  # 查找所有的 ip 记录
del trs[0]  # 删除标题的记录

with open(r'HTTP.txt', 'w+', ) as f:
	for tr in trs:
		tds = tr.find_all('td')  # 查找每个记录的具体信息,在这里或许可以称为分割
		f.write('http://' + tds[1].string + ':' + tds[2].string + '\n')

需要注意的是,西刺代理的网站也设置了反爬
你需要在访问 url 时把头信息加上,不然就会被403

获取了代理 IP,再就是在爬虫中使用
代码如下

# 爬虫--代理 IP

import random
from urllib import request

with open(r'HTTP.txt', 'r') as f:  # 从文件中载入代理 ip
	ips = f.read().split('\n')  # 以换行符分割

del ips[-1]  # 删除最后的空字符串

req = request.Request('https://www.baidu.com')  # 请求网址
req.add_header('User-Agent',
	'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36')  # 添加头信息

proxy_host = random.choice(ips)  # 随机选择一个 ip
proxy_temp = {'http': proxy_host}
proxy = request.ProxyHandler(proxy_temp)  # 设置代理
opener = request.build_opener(proxy, request.HTTPHandler)  # 创建一个 opener
request.install_opener(opener)  # 将 opener 设为全局

try:
	response = request.urlopen(req)  # 访问网页
except:
	print('终止交易!')
else:
	print(response.read().decode())  # 打印网页信息

上面就是在爬虫中使用代理 ip 的相关设置,如果成功的话可以直接获取到相应网页源码内容

当然也可以试试尝试 https 的代理 IP,这需要相关 SSL 安全证书验证的设置,而且很可能会被拒绝

如果没有访问成功,那有可能是你所使用的代理 IP 失效了(毕竟有些代理 IP 可能有效期只有几分钟)
要验证代理 IP 是否有效,很简单,放到 cmd 窗口中ping一下
ping
可以看出这个 IP 是可以连通的,尚处于有效期

但显然,我们总不能每次使用代理 IP 时都到 cmd 中去验证一下
这不太符合爬虫连续、高并发的特性

所以我们需要在我们的爬虫代码中加入验证

import subprocess

def ip_test(ip):
	proc = subprocess.Popen('ping ' + ip, stdout=subprocess.PIPE).communicate()[0]  # 执行命令,获取输出结果
	result = proc.decode()  # 转码 utf-8
	if result.find('100% 丢失') != -1:
		return False
	return True

需要注意的是,这里面的参数 ip 并不是从文件中 choice 出来的 proxy_host

从 proxy_host 中切割 ip (好像做了复杂工作)

ip = proxy_host.split('//')[1].split(':')[0]

proc 的转码也需要注意,有可能出现 utf-8 无法识别的字符,如果你的 cmd 使用的不是 utf-8 的编码格式(我们一般默认 GBK)
如果出现了转码错误,可以转成 GBK 试试
如果还不行,可以把 cmd 编码格式设成 utf-8

当然,我们使用爬虫爬取数据也需要有所节制,万万不可对人家的服务器无限制的请求,避免 DOS,从你做起

  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值