如何利用从CNKI抓取论文信息

在获得一片文章的时候,我们希望获得更多的的论文信息,比如论文的参考文献列表。但是CNKI没有给我们一个API,让我们这些屌丝学者无法尽可能多的获取文献信息。那么怎么办呢?会点编程的屌丝自有解决办法。

在使用文献统计与分析辅助工具获取文献元数据集之后,直接获得了可以查看文献详细信息的URL,形式如下:

http://www.cnki.net/kcms/detail/detail.aspx?dbname=cjfq2013&filename=flda201312014

两个参数即可确定该文献的详情页地址。接下来使用curl抓取该详情地址页的html数据。

function get_by_curl($url,$post = false){
  $ch = curl_init();
  curl_setopt($ch,CURLOPT_URL,$url);
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  if($post){
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
  }
  $result = curl_exec($ch);
  curl_close($ch);
  return $result;
}

$uri = $_SERVER['REQUEST_URI'];
$php = $_SERVER['SCRIPT_NAME'];

$url = str_replace($php.'?','',$uri);
if(strpos($url,'http') !== 0)exit();

$data = get_by_curl($url);

// 通过抓取获取论文标题
preg_match('/<h1 id="spanTitle"><span id="chTitle">(.*?)<\/span><\/h1>/',$data,$title);
$title = $title[1];

// 通过抓取获得了下载地址
preg_match('/<a.*?href="(.*?)"><b>PDF下载<\/b><\/a>/',$data,$download);
$download = $download[1];
$download = str_replace(' ','',$download);
$download = str_replace('&#xA;','',$download);
$download = str_replace('&amp;','&',$download);
$download = 'http://www.cnki.net'.$download;// 只要你登录了,就可以直接下载

// 通过抓取获取文件相关信息
preg_match('/SetRefChartDataEx\((.*?)\);/',$data,$info);
$info = $info[1];
$info = str_replace('\'','',$info);
$info = explode(',',$info);
//SetRefChartDataEx('CJFQ','ynda200701022','CJFQ2007','2007');
$filename = $info[1];
$dbcode = $info[0];
$dbname = $info[2];
$year = $info[3];

// 因为获取了dbcode,所以在url基础上在加上
$url .= "&dbcode={$dbcode}";

// 通过抓取获取当前登录用户的userid,这个userid是cnki随机分配的,必须使用它才能查看参考文献
preg_match('<input id="listv" type="hidden" value="(.*?)">',$data,$login);
$login = $login[1];

// 获取参考文献列表地址
$ref = "http://www.cnki.net/kcms/detail/frame/list.aspx?dbcode={$dbcode}&filename={$filename}&dbname={$dbname}&RefType=1&vl={$login}";

header('Content-Type: text/html; charset=utf-8');
echo "<title>{$title} - 档案学实验室</title>";
echo "<h1>{$title}</h1>";
echo "<p>详细地址:<input type='text' value='{$url}' onclick='this.select();'></p>";
echo "<p>下载地址:<input type='text' value='{$download}' onclick='this.select();'></p>";
echo "<p>参考文献:<input type='text' value='{$ref}' onclick='this.select();'></p>";

把上面得到的详情地址传入

get_detail.php?http://www.cnki.net/kcms/detail/detail.aspx?dbname=cjfq2013&filename=flda201312014

即可通过curl抓取到详情页面的html数据,再通过preg_match函数进行正则匹配,抓取想要的元数据。

通过URL的规则替换,还获得了下载地址、参考文献列表地址。因为通过curl抓取,发出请求的是自己的服务器,所以在本机上cnki记录的cookie和服务器上记录的不同,所以打开的时候看不到结果。解决的办法是,通过拷贝地址,在新窗口中打开,这样cnki认为你是一个新的用户,就会把数据返回给你。

如果我们不需要下载文献,通过curl抓取,就完全满足了我们的需要了。

2014-11-24