点击阅读原文进入 【VSRC征稿】宅家副业攻略请查收!
【VSRC唯科普】避开采集陷阱(第12/14篇)
鸣 谢
VSRC感谢业界小伙伴——Mils 投稿精品科普类文章。VSRC欢迎精品原创类文章投稿,优秀文章一旦采纳发布,将有好礼相送,我们已为您准备好了丰富的奖品!
(活动最终解释权归VSRC所有)
一般的,一个成熟的商业化网站,为了防止数据被自动化工具所采集,会对访问浏览器的行为,进行判断,网站会区分访问行为是正常用户所发起的,还是自动化程序或机器人所为,一旦发现非人为操作,则通常会进行拦截。而在数据采集期间,为了防止我们的自动化工具,被网站轻易的识别和拦截,今天的唯科普,将主要介绍以下三种方式,可以使得自动化程序对浏览器的访问行为,更接近正常用户,从而避免被网站拦截:
方法1、修改User Agent
方法2、处理Cookies
方法3、避免蜜罐
方法1.修改请求头User Agent
在唯科普9里面,我们曾经使用requests模块处理网站的表单信息,并且我们也知道了requests模块是一个设置请求头的利器。HTTP的请求头指的是在每次向网络服务器发送请求时,传递的一组属性和配置信息。HTTP定义了十几种请求头类型,其中包括以下七个常用字段,这七个常用字段会被大多数浏览器用来初始化网络请求:
Host
Connection
Accept
User-Agent
Referrer
Accept-Encoding
Accept-Language
经典的Python爬虫在使用urllib标准库时,都会发送如下的请求头:
Accept-Encoding
User-Agent
以下是一些Andriod、Firefox、Google Chrome、iOS的常用User Agent示例:
1.Android
Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19
Mozilla/5.0 (Linux; U; Android 4.0.4; en-gb; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Mozilla/5.0 (Linux; U; Android 2.2; en-gb; GT-P1000 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
2.Firefox
Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0
Mozilla/5.0 (Android; Mobile; rv:14.0) Gecko/14.0 Firefox/14.0
3.Google Chrome
Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36
Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19
4.iOS
Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3
Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A101a Safari/419.3
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
如果不加以修饰,默认的,使用Python爬虫的请求头则直接会显示带有Python版本字样的User-Agent,类似这样的请求,就会很容易被网站的反爬虫检测机制给拦截掉。而请求头可以使用requests模块进行自定义,以 https://www.whatismybrowser.com/ 网站为例,该网站可以帮助我们在线测试浏览器的属性,我们可以通过程序模拟来采集这个网站的信息,验证浏览器Cookie设置:
import requests
from bs4 import BeautifulSoup
session = requests.Session()
headers = {
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36",
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/wepp,*/*;q=0.8"
}
url = "https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending"
req = session.get(url,headers=headers)
bsObj = BeautifulSoup(req.text,"html.parser")
print (bsObj.find("table",{"class":"table-striped"}).get_text)
最终输出结果中的请求头,与应用程序中设置的headers是一样的。
方法2.处理Cookies
网站会使用cookie跟踪你访问的过程,如果发现自动化爬虫等异常行为,就会中断你的访问,比如特别快速的填写表单,或者浏览大量页面,虽然这些行为可以通过关闭并重新连接或改变IP地址来伪装,但是如果Cookie暴露了身份,再多努力也是白费。而正确的处理Cookie可以避免许多采集问题,当你在采集一个或几个目标网站时,建议检查这些网站生成的cookie,然后想下哪个cookie是需要爬虫处理的。有一些浏览器插件可以为你显示访问网站和离开网站时cookie是如何设置的。例如EditThisCookie就是一个非常好用的Chrome的浏览器插件之一。由于requests模块不能执行JavaScript,所以requests不能处理很多新式的跟踪软件生成的cookie,比如Google Analytics,只有当客户端脚本执行之后才设置cookie,或者用户在浏览页面时基于事件产生cookie,比如点击按钮。为了处理这些动作时,便会需要用到Selenium以及WebDriver。我们可以以http://pythonscraping.com为例,演示下如何调用WebDriver的GET方法来查看Cookie,示例代码如下:
from selenium import webdriver
exec_path = "C:\chromedriver.exe"
url = "http://pythonscraping.com/"
driver = webdriver.Chrome(executable_path=exec_path)
driver.get(url)
driver.implicitly_wait(1)
print (driver.get_cookies())
得到的返回信息如下,这样就能得到一个非常典型的Google Analytics的Cookie列表:
C:\Python37-x64\python.exe D:/phpStudy/WWW/VSRC_POP/CH12/webdriver_get_cookie.py
[{'domain': '.pythonscraping.com', 'expiry': 15****7, 'httpOnly': False, 'name': '_gid', 'path': '/', 'secure': False, 'value': 'GA1.2.5****03.158*****98'}, {'domain': '.pythonscraping.com', 'expiry': 164****97, 'httpOnly': False, 'name': '_ga', 'path': '/', 'secure': False, 'value': 'GA1.2.186****848.158****98'}, {'domain': '.pythonscraping.com', 'expiry': 158****57, 'httpOnly': False, 'name': '_gat', 'path': '/', 'secure': False, 'value': '1'}, {'domain': 'pythonscraping.com', 'httpOnly': False, 'name': 'has_js', 'path': '/', 'secure': False, 'value': '1'}]
Process finished with exit code 0
另外还可以调用delete_cookie(),add_cookie()和delete_all_cookies()的方法来处理cookie,还可以保存cookie以备其他网络爬虫使用。示例如下:
from selenium import webdriver
exec_path = "C:\chromedriver.exe"
url = "http://pythonscraping.com/"
driver1 = webdriver.Chrome(executable_path=exec_path)
driver1.get(url)
driver1.implicitly_wait(1)
print ("driver1 : ",driver1.get_cookies())
savedCookies = driver1.get_cookies()
driver2 = webdriver.Chrome(executable_path=exec_path)
driver2.get(url)
driver2.delete_all_cookies()
for cookie in savedCookies:
driver2.add_cookie(cookie)
driver2.get(url)
driver2.implicitly_wait(1)
print ("driver2 : ",driver2.get_cookies())
在这个例子中,第一个webdriver1获取了一个网站,打印cookie并把他们保存到变量savedCookies里。第二个webdriver2加载同一个网站,删除所有cookie,然后替换成第一个webdriver1得到的cookie,当再次加载这个页面时,两组cookie的时间戳,源代码及其他信息完全一致。于是,从Google Analytics的角度看,就会认为第二个webdriver和第一个webdriver是完全一样的。
方法3.避免蜜罐
虽然在进行网络数据采集时候用CSS属性区分有用信息和无用信息会比较容易,比如通过读取id和class标签获取信息,但是这么做有时也会出问题,如果网络表单的一个字段通过CSS设置成了对用户不可见,那么可以认为普通用户访问网站的时候不能填写这个字段,因为他没有显示在浏览器上,如果这个字段被填写了,就可能是机器人干的,因此这个提交会失效。这种手段不仅可以应用在网站的表单上,还可以应用在链接、图片、以及一些可以被机器人读取,但普通用户在浏览器上却看不到的任何内容上面,访问者如果访问了网站上的“隐含”内容,就会触发服务器脚本封杀这个用户的IP地址,把这个用户提出网站,或采取其他措施禁止这个用户接入网站。
在这个页面中,http://pythonscraping.com/pages/itsatrap.html,包含了两个链接,一个通过CSS隐含了,另外一个是可见的,并且页面上还包含了两个隐含字段:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>A bot-proof form</title>
</head>
<style>
body {
overflow-x:hidden;
}
.customHidden {
position:absolute;
right:50000px;
}
</style>
<body>
<h2>A bot-proof form</h2>
<a href="http://pythonscraping.com/dontgohere" style="display:none;">Go here!</a>
<a href="http://pythonscraping.com">Click me!</a>
<form>
<input type="hidden" name="phone" value="valueShouldNotBeModified"/><p/>
<input type="text" name="email" class="customHidden" value="intentionallyBlank"/><p/>
<input type="text" name="firstName"/><p/>
<input type="text" name="lastName"/><p/>
<input type="submit" value="Submit"/><p/>
</form>
</body>
</html>
这三个元素通过不同的方式对用户隐藏:
第一个链接是通过简单的CSS属性设置display:none进行隐藏
电话号码字段 name="phone"是一个隐含的输入字段
邮箱地址字段 name="email"是一个将元素向右移动50000像素并隐藏滚动条
因为Selenium可以获取访问页面的内容,所以他可以区分页面上的可见元素与隐含元素。通过is_display()可以判断元素在页面上是否可见。例如,以下这段代码显示就是可以获取前面那个页面的内容,然后查找隐含链接和隐含输入字段:
from selenium import webdriver
from selenium.webdriver.remote.webelement import WebElement
exec_path = "C:\chromedriver.exe"
driver = webdriver.Chrome(executable_path=exec_path)
driver.get("http://pythonscraping.com/pages/itsatrap.html")
links = driver.find_elements_by_tag_name("a")
for link in links:
if not link.is_displayed():
print ("The link" + link.get_attribute("href")+ "is a trap")
fields = driver.find_elements_by_tag_name("input")
for field in fields:
if not field.is_displayed():
print ("Do not change value of " + field.get_attribute("name"))
Selenium抓出了每一个隐含的链接字段,结果如图所示:
虽然我们通常不太可能会去访问那些隐藏的链接,但是在提交表单之前,记得确认一下那些已经在表单中、准备提交的隐含字段的值(或者让Selenium为你自动提交)。
参考资料
1、https://www.w3school.com.cn
2、https://www.python.org/
3、《Web Scraping with Python》
唯科普 | 《数据采集》目录
A.K.A "小白终结者"系列
第12篇、避开采集的陷阱
第13篇、用自动化程序测试网站
第14篇、远程采集
。
。
精彩原创文章投稿有惊喜!
VSRC欢迎精品原创类文章投稿,优秀文章一旦采纳发布,将为您准备的丰富奖金税后1000元现金或等值礼品,上不封顶!如若是安全文章连载,奖金更加丰厚,税后10000元或等值礼品,上不封顶!还可领取精美礼品!可点击“阅读原文”了解规则。(最终奖励以文章质量为准。活动最终解释权归VSRC所有)
不知道,大家都喜欢阅读哪些类型的信息安全文章?
不知道,大家都希望我们更新关于哪些主题的干货?
现在起,只要您有任何想法或建议,欢迎直接回复本公众号留言!
精彩留言互动的热心用户,将有机会获得VSRC赠送的精美奖品一份!
同时,我们也会根据大家反馈的建议,选取热门话题,进行原创发布!
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
随时掌握互联网精彩
- 1 这本书,智利总统带到秘鲁的会见厅 7954018
- 2 胖东来:员工不许靠父母买房买车 7978562
- 3 钟睒睒不建议长期喝绿瓶水 7866986
- 4 世界互联网大会有哪些新看点? 7736949
- 5 乌克兰首都基辅再次拉响防空警报 7681111
- 6 医院CT等收费将执行新规 7578245
- 7 19岁孤儿被骗到郑州4天没吃没喝 7491923
- 8 药监局:百雀羚不存在违规行为 7364708
- 9 3.69万吨大桥空中成功“转身” 7246523
- 10 科技与文化融合的“赛博”水乡 7132451