Python 實現 CNKI批量下載 和FireFox Extension 入門學習筆記

                                 Python 實現 CNKI批量下載 和FireFox Extension 入門學習筆記 javascript


      因爲須要也是爲了督促本身學習新的東西,我本來想要嘗試着寫一個爬蟲程序,可以在cnki上自動得將論文進行批量下載,學習過程當中遇到了諸多狀況,cnki也真是專業,不得不佩服cnki的強大。 java

下面進入正題: python


學習、實驗環境:ubuntu 14.04 chrome

工具:Eclipse ,  FireFoxFireBugHttpFox 編程

編程語言:python,   js,   XUL ubuntu


       因爲我是中山大學學生,使用校園網進入cnki進行下載是不用登陸的,因此我也就沒進行模擬登陸等方面的實現,有須要的朋友可使用splinter進行模擬登陸,也算快速便捷哈。 windows


       首先咱們要實現使用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粘貼到代碼中試一試成功了。 cookie


      下載部分的代碼成功了,那下面就是,如何從cnki的網頁中獲取到下載的url了,在這部分的實現中,我本來想要使用純python的實現,使用python寫一個爬蟲,直接上cnki進行抓取,可是具體實現的時候碰到了很大的問題,例如:1、爬蟲網頁動態生成的數據困難重重;2cnki網頁在瀏覽器顯示的url一直都是:」http://epub.cnki.net/kns/brief/default_result.aspx3、咱們須要的網頁是放在一個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="overlay.js"/>

  <menupopup id="menu_ToolsPopup">
    <menuitem id="DownLoadPaper" label="DownLoadPaper" oncommand="getURL();"/>
  </menupopup>

</overlay>


至此,這個粗糙的輔助插件就編寫完了,將文件打包壓縮成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
        refer = '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&t=1431252221059&keyValue=python&S=1'


        h = {
             'Referer' : refer,
             '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文件就能夠下載了。

相關文章
相關標籤/搜索