知网爬取研究 - wbwangk/wbwangk.github.io GitHub Wiki

知网的检索请求逻辑(推测)

我们是模仿浏览器向知网发送请求,模仿的越像浏览器越不容易触发知网的“反爬虫”系统。浏览器检索知网的地址是:http://epub.cnki.net/kns/brief/default_result.aspx。

###第一个URL:SearchHandler(发起检索)

  • URI:http://epub.cnki.net/kns/request/SearchHandler.ashx

这个请求是检索(搜索)的真正请求,会刷新数据缓存。之后的网页请求(brief)或翻页请求只是将数据封装为网页返回。在知网的网页实现中,这个是个AJAX请求。 URL参数txt_1_value1=lee中lee是要检索的内容。下面的URL是要检索作者是"lee"的作品清单(在网页下拉框中选择“作者”,输入lee然后点检索按钮):

curl -i 'http://epub.cnki.net/kns/request/SearchHandler.ashx?action=&NaviCode=*&ua=1.11&PageName=ASP.brief_default_result_aspx&DbPrefix=SCDB&DbCatalog=%e4%b8%ad%e5%9b%bd%e5%ad%a6%e6%9c%af%e6%96%87%e7%8c%ae%e7%bd%91%e7%bb%9c%e5%87%ba%e7%89%88%e6%80%bb%e5%ba%93&ConfigFile=SCDBINDEX.xml&db_opt=CJFQ%2CCJFN%2CCDFD%2CCMFD%2CCPFD%2CIPFD%2CCCND&txt_1_sel=AU%24%3D%7C&txt_1_value1=lee&txt_1_special1=%25&his=0&parentdb=SCDB&__=Wed%20Dec%2014%202016%2019%3A05%3A53%20GMT%2B0800%20(%E4%B8%AD%E5%9B%BD%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4)' -H 'Accept-Language: zh-CN,zh;q=0.8,en;q=0.6' -H 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36' -H 'Accept: */*' -H 'Referer: http://epub.cnki.net/kns/brief/default_result.aspx' -H 'Cookie: RsPerPage=20; Ecp_LoginStuts={"IsAutoLogin":false,"UserName":"dx1204","ShowName":"%e6%b5%aa%e6%bd%ae%e7%94%b5%e5%ad%90%e4%bf%a1%e6%81%af%e4%ba%a7%e4%b8%9a%e8%82%a1%e4%bb%bd%e6%9c%89%e9%99%90%e5%85%ac%e5%8f%b8","UserType":"bk","r":"j4l3if"}' -H 'Connection: keep-alive'

上述内容经过了URL编码,所以看上去有些乱。如果对于curl不是熟悉,参照curl简介。可以使用这个网页进行URL解码。

上述请求由于使用了-i参数,会显示服务器在cookie中写入的值,如:

Set-Cookie: ASP.NET_SessionId=kuqfzbut5q1332lnofibxk5y; path=/; HttpOnly
...

请求SearchHandler这个URL的目的,除了将检索结果写入数据缓存,另一个用处是获取ASP.NET_SessionId(相当于jsessionid)。这个会话id将在下面的URL中用到。如果下面URL的会话id不正确或缺少将服务正确返回检索结果。 ###第二个URL:brief(取检索结果清单)

  • URI:http://epub.cnki.net/kns/brief/brief.aspx

通过这个地址获取检索的结果网页,同时翻页也是这个URI,只是参数不同。 URL参数keyValue=lee中lee是要检索的内容。实测中检索内容是受SearchHandler请求决定的,即使brief请求中传入不同的keyValue也不管用。发出brief请求时,需要把SearchHandler请求写入cookie的ASP.NET_SessionId值一并发往服务器。 brief请求完整URL例子如下:

curl -i 'http://epub.cnki.net/kns/brief/brief.aspx?pagename=ASP.brief_default_result_aspx&dbPrefix=SCDB&dbCatalog=%e4%b8%ad%e5%9b%bd%e5%ad%a6%e6%9c%af%e6%96%87%e7%8c%ae%e7%bd%91%e7%bb%9c%e5%87%ba%e7%89%88%e6%80%bb%e5%ba%93&ConfigFile=SCDBINDEX.xml&research=off&keyValue=lee&S=1' -H 'Accept-Language: zh-CN,zh;q=0.8,en;q=0.6' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Referer: http://epub.cnki.net/kns/brief/default_result.aspx' -H 'Cookie: ASP.NET_SessionId=kuqfzbut5q1332lnofibxk5y; RsPerPage=20; Ecp_LoginStuts={"IsAutoLogin":false,"UserName":"dx1204","ShowName":"%e6%b5%aa%e6%bd%ae%e7%94%b5%e5%ad%90%e4%bf%a1%e6%81%af%e4%ba%a7%e4%b8%9a%e8%82%a1%e4%bb%bd%e6%9c%89%e9%99%90%e5%85%ac%e5%8f%b8","UserType":"bk","r":"j4l3if"}' -H 'Connection: keep-alive'

参数RsPerPage定义了每页显示的记录数,可选值有10、20、50。必须保证ASP.NET_SessionId与SearchHandler请求写入cookie中值相等,否则会报错。 ###第三个URL:brief(检索结果翻页) URI:http://epub.cnki.net/kns/brief/brief.aspx

翻页请求的完整URL:

curl -i 'http://epub.cnki.net/kns/brief/brief.aspx?curpage=2&RecordsPerPage=20&QueryID=0&ID=&turnpage=1&tpagemode=L&dbPrefix=SCDB&Fields=&DisplayMode=listmode&PageName=ASP.brief_default_result_aspx' -H 'Accept-Language: zh-CN,zh;q=0.8,en;q=0.6' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Referer: http://epub.cnki.net/kns/brief/brief.aspx?pagename=ASP.brief_default_result_aspx&dbPrefix=SCDB&dbCatalog=%e4%b8%ad%e5%9b%bd%e5%ad%a6%e6%9c%af%e6%96%87%e7%8c%ae%e7%bd%91%e7%bb%9c%e5%87%ba%e7%89%88%e6%80%bb%e5%ba%93&ConfigFile=SCDBINDEX.xml&research=off&keyValue=lee&S=1' -H 'Cookie: ASP.NET_SessionId=kuqfzbut5q1332lnofibxk5y; RsPerPage=20' -H 'Connection: keep-alive'

参数中curpage表示当前网页序号。仍需要注意ASP.NET_SessionId值的正确性。http请求头中的Referer表示http链接的来源网页URL,应填入第二个URL。

##其他 ###http压缩 用浏览器访问知网时是启用gzip压缩的,如果用curl模拟压缩请求,需要用到--compressed参数,而且要在http头中增加'Accept-Encoding: gzip, deflate, sdch'。以第一个URL为例:

curl -i -c tos.txt 'http://epub.cnki.net/kns/request/SearchHandler.ashx?action=&NaviCode=*&ua=1.11&PageName=ASP.brief_default_result_aspx&DbPrefix=SCDB&DbCatalog=%e4%b8%ad%e5%9b%bd%e5%ad%a6%e6%9c%af%e6%96%87%e7%8c%ae%e7%bd%91%e7%bb%9c%e5%87%ba%e7%89%88%e6%80%bb%e5%ba%93&ConfigFile=SCDBINDEX.xml&db_opt=CJFQ%2CCJFN%2CCDFD%2CCMFD%2CCPFD%2CIPFD%2CCCND&txt_1_sel=AU%24%3D%7C&txt_1_value1=lee&txt_1_special1=%25&his=0&parentdb=SCDB&__=Wed%20Dec%2014%202016%2019%3A05%3A53%20GMT%2B0800%20(%E4%B8%AD%E5%9B%BD%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4)' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Accept-Language: zh-CN,zh;q=0.8,en;q=0.6' -H 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36' -H 'Accept: */*' -H 'Referer: http://epub.cnki.net/kns/brief/default_result.aspx' -H 'Cookie: RsPerPage=20; Ecp_LoginStuts={"IsAutoLogin":false,"UserName":"dx1204","ShowName":"%e6%b5%aa%e6%bd%ae%e7%94%b5%e5%ad%90%e4%bf%a1%e6%81%af%e4%ba%a7%e4%b8%9a%e8%82%a1%e4%bb%bd%e6%9c%89%e9%99%90%e5%85%ac%e5%8f%b8","UserType":"bk","r":"j4l3if"}' -H 'Connection: keep-alive' --compressed

###centos与ubuntu 本来使用curl的-c/-b参数可以简化替换会话值的工作量,如curl -c cookie.txt http://...。实测-c/-b参数在ubuntu下可以,但在centos下不行,原因不明。