点击阅读原文进入 ? 【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 中央经济工作会议在北京举行 7904200
- 2 紧急提醒:请在日中国公民进行登记 7808244
- 3 中央定调明年继续“国补” 7714421
- 4 “九天”无人机成功首飞 7618818
- 5 断崖式降温!今冬最强寒潮来了 7521789
- 6 中央经济工作会议释信号:3件事不做 7427070
- 7 中国“空中航母”首飞成功 7329097
- 8 《时代》周刊2025年度人物公布 7232121
- 9 人民空军中日双语发文:大惊小怪 7137867
- 10 寒潮来袭 “速冻”模式如何应对 7047012







唯品会安全
