利用爬蟲批量下載論文(python+selenium)

本文來自於導師布置的一次任務,任務需要把econometrica從2000年以來的所有文章下載下來,我估計了一下,大概有將近1500篇論文,這一個一個手動下載,下到什麼時候是個頭喲,自然就想到了用爬蟲。

我開始是抓的JSTOR資料庫,但是當時對selenium還不熟,寫的比較啰嗦,而且JSTOR上的Econometrica只更新到2014年,所以在這裡就不放爬JSTOR的代碼了,只放爬wiley的代碼。

Wiley 的Econometrica 每一期都有個單獨頁面,這個頁面的url很有特點,可以從wiley的econometrica主頁上爬,也可以直接生成,在這裡我就直接生成了。然後我要明確在每一期的頁面上要爬到的數據:pdf下載地址、年份、卷、頁碼、論文標題,我要用這幾個數據組成pdf文件的標題。這些元素用selenium的xpath定位非常容易。

爬好pdf下載地址就可以下載了,下載到文件夾里然後按一定的命名規則重命名,就搞定了。

# coding=utf-8import timeimport csvimport osfrom selenium import webdriverfrom pyvirtualdisplay import Display# 得到每一期主頁的網址def get_issue_url(begin_year,end_year): issue_url_list=[] for j in range(begin_year,end_year): year_num=str(j) VOL_num=str(j-1932) for i in range(1,7): issue_num=str(i) issue_url=http://onlinelibrary.wiley.com/doi/10.1111/ecta.%s.%s.issue-%s.x/issuetoc%(year_num,VOL_num,issue_num) issue_url_list.append(issue_url) return issue_url_list[:-3]# 得到一期內每個文章(非評論類文章)網址def get_pdf_url(issue_url): driver.get(issue_url) time.sleep(5) Issue_num = driver.find_elements_by_xpath(//span[@class="issueTocIssue"])[0].text Vol_num = driver.find_elements_by_xpath(//span[@class="issueTocVolume"])[0].text year_num = driver.find_elements_by_xpath(//h2[@class="noMargin"])[0].text[-4:] one_issue_pdf_url_list = [] one_issue_file_title_list=[] one_issue_title_list=[] one_issue_page_list=[] for link in driver.find_elements_by_xpath(//*[@id="group2"]/ol/li/div/a): url = link.get_attribute(href)[:-4]+pdf title,page=link.text[:-1].split( () file_title=year_num+-+Issue_num+-+Vol_num+-+page one_issue_pdf_url_list.append(url) one_issue_file_title_list.append(file_title) one_issue_title_list.append(title) one_issue_page_list.append(page) print file_title one_issue_dl_file_name_list=[] for url in one_issue_pdf_url_list: # wiley上econometrica的文章,網址末尾和下載下來的文件名不同,所以需要爬兩次,有的期刊則不用,比如JF full_url = url[:-3]+full driver.get(full_url) try: link= driver.find_elements_by_xpath(//li[@class="article-header__references-item"])[0] dl_file_name=link.get_attribute(id).split(-)[0].lower() except: dl_file_name=ecta+str(int(dl_file_name[4:])+1) print Error! No ecta number! print dl_file_name one_issue_dl_file_name_list.append(dl_file_name) return one_issue_pdf_url_list,one_issue_dl_file_name_list,one_issue_file_title_list,one_issue_title_list,one_issue_page_list# pdf下載函數def download_pdf(driver,pdf_url): display=Display(visible=0,size=(800,600)) display.start() driver.get(pdf_url) time.sleep(3) display.stop()# 保存csv函數def save_csv(data,first_row): csvfile = file(/Users/your_path/title.csv, wb) writer = csv.writer(csvfile) writer.writerow(first_row) writer.writerows(data) csvfile.close()if __name__==__main__: # 定義driver options = webdriver.ChromeOptions() prefs = { "download.prompt_for_download": False, download.default_directory: /Users/your_path, "plugins.always_open_pdf_externally": True } options.add_experimental_option(prefs, prefs) driver = webdriver.Chrome(executable_path=/Users/your_path/chromedriver/chromedriver, chrome_options=options) # 爬取URL網址 begin_year=2015 end_year=2018 issue_url_list=get_issue_url(begin_year,end_year) pdf_url_list=[] dl_file_name_list=[] file_title_list=[] title_list=[] page_list=[] for issue_url in issue_url_list: one_issue_pdf_url_list, one_issue_dl_file_name_list,one_issue_file_title_list, one_issue_title_list, one_issue_page_list=get_pdf_url(issue_url) pdf_url_list=pdf_url_list+one_issue_pdf_url_list dl_file_name_list=dl_file_name_list+one_issue_dl_file_name_list file_title_list = file_title_list+one_issue_file_title_list title_list = title_list+one_issue_title_list page_list = page_list+one_issue_page_list # 轉碼並保存為csv for i in range(len(pdf_url_list)): pdf_url_list[i]=pdf_url_list[i].encode(utf8) dl_file_name_list[i]=dl_file_name_list[i].encode(utf8) file_title_list[i]=file_title_list[i].encode(utf8) title_list[i]=title_list[i].encode(utf8) page_list[i]=page_list[i].encode(utf8).replace(ü,_) data = zip(pdf_url_list,dl_file_name_list,file_title_list, title_list, page_list) save_csv(data, [pdf_url,download_file_name,file_name,paper_title,page]) # 下載pdf data=csv.reader(open(/Users/your_path/title.csv)) data_list=[] for row in data: data_list.append(row) pdf_url_list,dl_file_name_list,file_new_name_list,paper_name_list,page_list=map(list, zip(*data_list[1:])) disk_name_list = os.listdir(/Users/your_path) for i in range(len(pdf_url_list)): # 防止重複下載 file_name=dl_file_name_list[i]+.pdf if file_name not in disk_name_list: url=pdf_url_list[i] download_pdf(driver, url) # 重命名 disk_name_list = os.listdir(/Users/your_path) for old_name in disk_name_list: old_name=old_name.split(.)[0] if old_name in dl_file_name_list: new_name=file_new_name_list[dl_file_name_list.index(old_name)] os.rename(/Users/your_path + old_name+.pdf, /Users/your_path+ new_name + .pdf)

本文只是一個門外漢寫的一小段代碼罷了,目的就是能用,只希望能幫助非計算機專業的同學們簡化研究工作中的重複勞動。所以應用環境也必須是校園網之下,學校還得是買了wiley或JSTOR資料庫的。校外上網涉及到vpn的問題,我也沒有繼續研究,直接利用校園網下載了。

希望能幫到看到這篇文的你。

推薦閱讀:

python 3.5 中 PEP0484 新加入的 Type Hints 的使用方法是什麼?
為什麼可以像執行系統命令一樣執行 Python 的包,如 scrapy crawl xxx?
anaconda中如何安裝keras?
反反爬蟲利器!教你怎麼用代理,撥號換IP……
Python 黑客相關電子資源和書籍推薦

TAG:Python | Selenium | 爬虫 |