首页 > 代码库 > Python 实现 CNKI批量下载 和FireFox Extension 入门学习笔记

Python 实现 CNKI批量下载 和FireFox Extension 入门学习笔记

?                                 Python 实现 CNKI批量下载 和FireFox Extension 入门学习笔记?


      由于需要也是为了督促自己学习新的东西,我原本想要尝试着写一个爬虫程序,能够在cnki上自动得将论文进行批量下载,学习过程中遇到了诸多情况,cnki也真是专业,不得不佩服cnki的强大。

下面进入正题:


学习、实验环境:ubuntu 14.04

工具:Eclipse ,  FireFoxFireBugHttpFox

编程语言:python,   js,   XUL


       由于我是中山大学学生,使用校园网进入cnki进行下载是不用登录的,所以我也就没进行模拟登录等方面的实现,有需要的朋友可以使用splinter进行模拟登录,也算快速便捷哈。


       首先我们要实现使用pythoncnki的论文实现批量下载,我们首先要对客户端和服务器之间相互传递的信息进行了解,这里我第一次使用的是wireshark,但是这个工具虽然强大,但是真不利于我们进行分析,它抓取的是我们电脑端口的信息,而不能只抓取当前网页的,在多次尝试之后我选择了HttpFox进行数据包抓取:



       如图我们可以发现cnki对一个下载进行了3redirect,我们通过对获得的数据和再一次发送的数据对比可以发现:前一次获得的url就是下一次geturl,所以我们就可以写出下载部分的核心代码,只有一点点是自己写的,许多网上一搜就有。

# -*- coding: UTF-8 -*-
import sys
import urllib2
import cookielib  
import string
import re
import time
cj = cookielib.CookieJar()  
cookie_support = urllib2.HTTPCookieProcessor(cj)  
opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)  
urllib2.install_opener(opener)
url = ‘http://epub.cnki.net/kns/download.aspx?filename=MBnRwcDMudGaItiamtScHVzb2Y0ZrVWRCBjaykEVXRTOjV0QHxUcTh3KNFXbHBDTyQVMNR2cP9kYGh1SXZnQnp3b3I2YqBnbUJ3KSNnRvpEUwhWTVJjNKBDcXVnSmZUayMkRVJUdytCe1AjT1ImTYdWdth1RtlGb&tablename=CMFDLAST2013‘
h = {
    ‘Referer‘ : url,
    ‘User-Agent‘ : ‘Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0‘
}
r = urllib2.urlopen(urllib2.Request(url,headers = h))

r = urllib2.urlopen(urllib2.Request(r.geturl(),headers = h))
r = urllib2.urlopen(urllib2.Request(r.geturl(),headers = h))
r = urllib2.urlopen(urllib2.Request(r.geturl(),headers = h))

data = r.read()

print data

      使用FireBug获取网页源代码,随意找几个下载图标的链接url粘贴到代码中试一试成功了。


      下载部分的代码成功了,那下面就是,如何从cnki的网页中获取到下载的url了,在这部分的实现中,我原本想要使用纯python的实现,使用python写一个爬虫,直接上cnki进行抓取,但是具体实现的时候碰到了很大的问题,例如:1、爬虫网页动态生成的数据困难重重;2cnki网页在浏览器显示的url一直都是:”http://epub.cnki.net/kns/brief/default_result.aspx”3、我们需要的网页是放在一个iframe标签里面的,这就非常蛋疼了,一直没找到获取办法


在同学的提示下,我发现了也许FireFox Extension是可行的解决方案。

       学习FireFox Extension的话首先需要能至少看懂XUL代码,然后基本的模范着写,然后呢,就得学会javascript了,当然也有不用js实现的插件,例如使用python写,那使用PyXPCOM,但是我还没学会,这里页不需要哈。


()FF extension总体认知

      FF是基于mozilla内核的,其浏览器引擎功能主要由C语言实现,但其浏览器界面及其界面上的相关操作都是由JSXUL完成的,这就是FF的强大之处,同时它也为大家提供了很好的扩展机制。

      FF扩展的开发目录结构:

      可以到官网上仔细看看。



   FF的工作方式:  

       对于任何一种新的开发语言或环境,大家通常都试图去寻找程序的入口点。可以很负责任地跟大家说,任何编译型(解释型程序)开发语言的程序都有类似C中的Main函数、Java中的主类(public static void main函数)C#中的入口函数(static void/int Main)等作为程序入口。

        这里我们呢了解这些也就够了。


这里我的目录结构是:

      --chrome

           --content

                  --overlay.js

                  --sample.xul

      --chrome.manifest

      --install.rdf


其中install.rdf代码为:

<?xml version="1.0"?>

<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:em="http://www.mozilla.org/2004/em-rdf#">

  <Description about="urn:mozilla:install-manifest">
    <em:id>sample@example.net</em:id>
    <em:version>1.0</em:version>
    <em:type>2</em:type>
   
    <!-- Target Application this extension can install into, 
         with minimum and maximum supported versions. --> 
    <em:targetApplication>
      <Description>
        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
        <em:minVersion>1.5</em:minVersion>
        <em:maxVersion>4.0.*</em:maxVersion>
      </Description>
    </em:targetApplication>
   
    <!-- Front End MetaData -->
    <em:name>DownLoadPaper</em:name>
    <em:description>A test extension</em:description>
    <em:creator>Liang</em:creator>
    <em:homepageURL>http://www.example.com/</em:homepageURL>
  </Description>      
</RDF>



chrome.manifest代码为

overlay chrome://browser/content/browser.xul chrome://sample/content/sample.xul
content     sample    chrome/content/


overlay.js代码为:

function getURL() {
  if ( window.content.document.location.href != "  {
  alert("Worng address");
  } else {          
    var myWin = window.content.document.getElementById(‘iframeResult‘).contentWindow;
    var hre = myWin.document.getElementsByClassName(‘brief_downloadIcon‘);
    var path = prompt("save address","eg. //****/****");
    path = path + "/test.csv";
    try {
    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
    } catch (e) {
     alert("no permisson...");
     }
    var file = Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsILocalFile);  
    file.initWithPath(path);
    if ( file.exists() == false )  {   
      file.create( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 420 );   
      }   
    var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"] .createInstance( Components.interfaces.nsIFileOutputStream );  
    outputStream.init( file, 0x04 | 0x08 | 0x20, 420, 0 );   
    var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"] .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
    for (var i = 0; i < hre.length; i++) {
      converter.charset = ‘UTF-8‘;
      var convSource = converter.ConvertFromUnicode(hre[i].href+"\n");
      var result = outputStream.write( convSource, convSource.length ); 
      }
    outputStream.close();  
    alert("File was saved in "+path);
    }
}


sample.xul代码如下:

<?xml version="1.0"?>
<overlay id="sample"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

  <script type="application/x-javascript" src=http://www.mamicode.com/"overlay.js"/>> 


至此,这个粗糙的辅助插件就编写完了,将文件打包压缩成zip格式,然后改名后缀为.xpi,再拖入FF就能安装了,这里需要修改一下FF的权限,使得插件能够修改本地文件,这样,工具栏里会多出一个工具,点击就能把论文下载的URL下载到一个test.csv的文件里了,windows下的用户就不要存到C盘里哈。

完整python文件为:

# -*- coding: UTF-8 -*-
import sys
import urllib2
import cookielib  
import string
import re
import time

f = open(‘test.csv‘, ‘r‘)
i = 1
for line in f:
    print line
    try:
        cj = cookielib.CookieJar()  
        cookie_support = urllib2.HTTPCookieProcessor(cj)  
        opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)  
        urllib2.install_opener(opener)
        url = line
        h = {
             ‘Referer‘ : url,
             ‘User-Agent‘ : ‘Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0‘
        }
        r = urllib2.urlopen(urllib2.Request(url,headers = h))

        r = urllib2.urlopen(urllib2.Request(r.geturl(),headers = h))
        r = urllib2.urlopen(urllib2.Request(r.geturl(),headers = h))
        r = urllib2.urlopen(urllib2.Request(r.geturl(),headers = h))

        data = r.read()
        
        if data[:8] == ‘[TARGET]‘:
            with open(str(i)+".caa", "wb") as up:     
                up.write(data)
            up.close
        else:
            with open(str(i)+".caj", "wb") as up:     
                up.write(data)
            up.close
        print str(i)+‘ ‘+‘succeed‘
        time.sleep(2)
    except:
        print str(i)+‘ ‘+‘failed‘
    i = i + 1


这样,将test.csv与python文件放于相同目录下,运行python文件就可以下载了。












Python 实现 CNKI批量下载 和FireFox Extension 入门学习笔记