搜狗陌陌采集 —— python爬虫系列一
优采云 发布时间: 2020-07-24 08:00前言:一觉醒来,发现原有的搜狗陌陌爬虫失效了,网上查找一翻发觉10月29日搜狗陌陌改版了,无法通过搜索公众号名子获取对应文章了,不过通过搜索主题获取对应文章还是可以的,问题不大,开搞!
目的:获取搜狗陌陌中搜索主题返回的文章。
涉及反爬机制:cookie设置,js加密。
完整代码已上传本人github,仅供参考。如果对您有帮助,劳烦看客大人给个星星!
进入题外话。
打开搜狗陌陌,在搜索框输入“咸蛋超人”,这里搜索下来的就是有关“咸蛋超人”主题的各个公众号的文章列表:
按照正常的采集流程,此时按F12打开浏览器的开发者工具,利用选择工具点击列表中文章标题,查看源码中列表中文章url的所在位置,再用xpath获取文章url的值,也就是这个href的值,为防止混乱,我们称之为“列表页面的文章url”。
可以见到“列表页面的文章url”需要拼接,一般这些情况须要在浏览器中正常访问一下这篇文章,对比观察跳转后的url(我们称之为“真实的文章url”),再缺头补头缺腿补腿即可。下面是两个url的对比:
列表页面的文章url:
/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSwqn5HZrcjUNFzn4G2S0Yt3MduzuCU92ulqXa8Fplpd9CqUiLuEm9hLLvBiu5ziMS196rgHYb-GzQfleG917OgwN_VAAdAZHKryCeU9lIxtWTKn*敏*感*词*csuPIjLhLEK3tbGSa3_pkMzadQg75Zhmxb9YI0psZvVepKtN4hpzQgtGa2iOlKKLwV_oxooGE6sxg1qinKxTb5VwJUcLBM1RgkzAPRtmyIGw2VAg..&type=2&query=%E5%92%B8%E8%9B%8B%E8%B6%85%E4%BA%BA&k=92&h=z
真实的文章url:
https://mp.weixin.qq.com/s?src=11&timestamp=1573092595&ver=1959&signature=FjD709D-0vHSyVgQyXCS-TUAcnT0M9Gx6JljQEb6O55zpuyyDaTHqgkRCxNDtt5ZDifDRUUBOemzxcz71FMOmO88m6RWfR0r4fFBe0VefAsjFu0pl-M0frYOnXPF5JD8&new=1
这里很明显两个url的路径不一致,应该是中间经过了一些调转,python的requests库是带手动调转功能,我们先把域名补上试一下访问
明显这儿做了反爬限制,那么这儿开始,我们就须要抓包剖析了。这里用到的工具是Firefox浏览器的开发者工具。抓包观察的是从搜索结果页面列表文章点击跳转到文章页面的过程,这里点击文章超链接会在新窗口打开,我们只须要在网页源码中把对应a标签的target属性改为空搜狗微信文章采集,就可以在一个窗口中观察整个流程的数据包了。
抓包剖析:
通过抓包我们可以找到搜索结果页面跳转到文章页面的过程,这里观察发觉,“列表页面的文章url”返回的结果中就包含了“真实的文章url”的信息,这意味着我们只须要正确访问到“列表页面的文章url”,根据返回的数据能够拼接出“真实的文章url”并访问了,这样我们就实现从“列表页面的文章url”到“真实的文章url”的跳转了!
此时我们的目标就从获取“真实的文章url”转变到正确的访问“列表页面的文章url”了,继续剖析抓包数据中的“列表页面的文章url”信息:
抓包数据:
url:https://weixin.sogou.com/link?url=dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSwqn5HZrcjUNEnNekGBXt9LMduzuCU92ulqXa8Fplpd9CqUiLuEm9hLLvBiu5ziMS196rgHYb-GzQfleG917OgwN_VAAdAZHKryCeU9lIxtWTKn*敏*感*词*csuPIjLhLEK3tbGaBLLLEV3E0vo604DcwbvX2VNudQZNnBemevd34BJP94ZL5zUiA49LgzIjRlpGxccVxTTaLhHZKstaeqw41upSVAe0f8bRARvQ..&type=2&query=%E5%92%B8%E8%9B%8B%E8%B6%85%E4%BA%BA&k=60&h=U
method:GET
请求参数:{"url":"dn9a_-gY295K0Rci_xozVXfdMkSQTLW6cwJThYulHEtVjXrGTiVgSwqn5HZrcjUNEnNekGBXt9LMduzuCU92ulqXa8Fplpd9CqUiLuEm9hLLvBiu5ziMS196rgHYb-GzQfleG917OgwN_VAAdAZHKryCeU9lIxtWTKn*敏*感*词*csuPIjLhLEK3tbGaBLLLEV3E0vo604DcwbvX2VNudQZNnBemevd34BJP94ZL5zUiA49LgzIjRlpGxccVxTTaLhHZKstaeqw41upSVAe0f8bRARvQ..","type":"2","query":"咸蛋超人","k":"60","h":"U"}
headers:
Host: weixin.sogou.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Referer: https://weixin.sogou.com/weixin?type=2&query=%E5%92%B8%E8%9B%8B%E8%B6%85%E4%BA%BA&ie=utf8&s_from=input&_sug_=n&_sug_type_=1&w=01015002&oq=&ri=1&sourceid=sugg&sut=750912&sst0=1573092594229&lkt=0%2C0%2C0&p=40040108
Cookie: 见下
Cookie:{"ABTEST":"4|1573094886|v1","IPLOC":"CN4401","JSESSIONID":"aaa3VBk4eXnIf8d4bdx4w","SNUID":"57A28ED20A0F9FB2BBE3E0180AF00D25","SUID":"5EAB87DB2613910A000000005DC385E6","SUV":"00F221C2DB87AB5E5DC385E7B*敏*感*词*3F633"}
这里的重点有三个:
请求参数:对比我们获取的“列表页面的文章url”分析可以发觉,这里多了两个参数“k”、“h”,这是须要我们设法获取的。headers:经过测试该网站对User-Agent敏感,一次访问前后User-Agent须要一致。Cookie:Cookie中参数须要获取能够正确访问该url。这些参数分别是:ABTEST、IPLOC、JSESSIONID、SNUID、SUID、SUV。
3.1:获取参数“k”、“h”
按照经验,从一个url转变成另一个url有两种情况:跳转和javascript字符串处理。经过多次抓包剖析发觉,搜索结果页面点击文章超链接到我们现今的目标url并没有存在跳转情况,抓包数据中的“列表页面的文章url”和我们获取的“列表页面的文章url”可以判断为同一个url,所以推测为javascript字符串处理。经过一番搜救,发现搜索结果页面的源码中有一段十分可疑的代码:
<script>
(function(){$("a").on("mousedown click contextmenu",function(){var b=Math.floor(100*Math.random())+1,a=this.href.indexOf("url="),c=this.href.indexOf("&k=");-1!==a&&-1===c&&(a=this.href.substr(a+4+parseInt("21")+b,1),this.href+="&k="+b+"&h="+a)})})();
</script>
这其中最重要的代码就是:this.href+="&k="+b+"&h="+a,这代码就是在点击风波发生时给a标签href属性的内容添加"&k="、"&h=",正是用这段代码对该url的参数进行js加密和添加的。我们只须要把这段代码用python实现就可以解决这个问题了,下面是实现python实现代码:
def get_k_h(url): <br /> b = int(random.random() * 100) + 1
a = url.find("url=")
url = url + "&k=" + str(b) + "&h=" + url[a + 4 + 21 + b: a + 4 + 21 + b + 1]<br /> reuturn url
3.2:获取Cookie的参数
观察抓包数据可以发觉,当我们一开始访问时并没有带任何cookie,但经过一系列恳求,到我们的目标恳求时侯,浏览器早已通过上面恳求的返回数据包的Set-Cookie属性把Cookie构造下来了,而我们要做的就是在Cookie构造从无到有这个过程中找到所有ResponseHeaders中带SetCookie属性的并且参数是我们须要的参数的恳求,并模拟访问一遍,就能得到所有参数并建立出我们须要的Cookie了。
例如搜狗微信搜索插口的恳求的ResponseHeaders就有5个Set-Cookie数组,其中ABTEST、SNUID、IPLOC、SUID都是我们最终构造Cookie所需的参数(和最后的Cookie值对比可以发觉,这里的SUID值还不是我们最终须要的,要在前面的数据包中继续开掘)。
经过剖析搜狗微信文章采集,经过四个恳求获取到的ResponseHeaders后我们能够正确建立Cookie了:
1. 得到ABTEST、SNUID、IPLOC、SUID:<br /> https://weixin.sogou.com/weixin?type=2&query=%E5%92%B8%E8%9B%8B%E8%B6%85%E4%BA%BA&ie=utf8&s_from=input&_sug_=n&_sug_type_=1&w=01015002&oq=&ri=1&sourceid=sugg&sut=750912&sst0=1573092594229&lkt=0%2C0%2C0&p=40040108<br />2. 需要IPLOC、SNUID,得到SUID:<br /> https://www.sogou.com/sug/css/m3.min.v.7.css<br />3. 需要ABTEST、IPLOC、SNUID、SUID,得到JSESSIONID:<br /> https://weixin.sogou.com/websearch/wexinurlenc_sogou_profile.jsp<br />4. 需要IPLOC、SNUID、SUID,得到SUV<br /> https://pb.sogou.com/pv.gif<br />
这四个恳求都能依照上面恳求获取到的Cookie参数来构造自己须要的Cookie去正确访问。值得注意的是最后一个恳求,除了须要正确拼接Cookie外,还须要获取正确的恳求参数能够正常访问:
这种找参数的活可以借助浏览器的全局搜索功能,一番搜救后,就会发觉在搜索结果页面的源代码中早已返回了这儿所需的所有参数,用正则把那些参数解析下来即可:
那么按照这种解析下来的参数和上面三个恳求得到的Cookie参数能够正确访问第四个恳求并得到所需的所有Cookie参数啦!
此时,我们早已剖析出所有正确模拟恳求的流程了,梳理一下:
获取“k”、“h”参数,传入搜索结果页面得到的“列表页面的文章ur”,调用get_k_h()即可。获取所需Cookie参数,构造正确的Cookie,按照流程三给出的4个url,分别构造恳求获取ResponseHeaders中的SetCookie即可。构造正确的恳求访问“列表页面的文章url”。根据3中恳求返回的数据,拼接出“真实的文章url”,也就是流程二。请求“真实的文章url”,得到真正的文章页面数据。
至此,所有剖析结束,可以愉快的码代码啦!
结语:此次采集涉及到的反爬技术是Cookie构造和简答的js加密,难度不大,最重要的是耐心和悉心。此外提醒诸位看客大人遵守爬虫道德,不要对别人网站造成伤害,peace!