<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          重大優(yōu)化!Python文獻超級搜索下載工具

          共 5907字,需瀏覽 12分鐘

           ·

          2021-01-25 15:04

          文獻搜索對于廣大學子來說真的是個麻煩事,如果你的學校購買的論文下載權限不夠多,或者不在校園內,那就很頭痛了。幸好,我們有Python制作的這個論文搜索工具,簡化了我們學習的復雜性

          1. 什么是Scihub

          首先給大家介紹一下Sci-hub這個線上數(shù)據(jù)庫,這個數(shù)據(jù)庫提供了約8千萬篇科學學術論文和文章下載。由一名叫亞歷珊卓·艾爾巴金的研究生建立,她過去在哈佛大學從事研究時發(fā)現(xiàn)支付所需要的數(shù)百篇論文的費用實在是太高了,因此就萌生了創(chuàng)建這個網(wǎng)站,讓更多人獲得知識的想法


          后來,這個網(wǎng)站越來越出名,逐漸地在更多地國家如印度、印度尼西亞、中國、俄羅斯等國家盛行,并成功地和一些組織合作,共同維護和運營這個網(wǎng)站。到了2017年的時候,網(wǎng)站上已有81600000篇學術論文,占到了所有學術論文的69%,基本滿足大部分論文的需求,而剩下的31%是研究者不想獲取的論文。

          2. 為什么我們需要用Python工具下載

          在起初,這個網(wǎng)站是所有人都能夠訪問的,但是隨著其知名度的提升,越來越多的出版社盯上了他們,在2015年時被美國法院封禁后其在美國的服務器便無法被繼續(xù)訪問,因此從那個時候開始,他們就跟出版社們打起了游擊戰(zhàn)

          游擊戰(zhàn)的缺點就是導致scihub的地址需要經常更換,所以我們沒辦法準確地一直使用某一個地址訪問這個數(shù)據(jù)庫。當然也有一些別的方法可讓我們長時間訪問這個網(wǎng)站,比如說修改DNS,修改hosts文件,不過這些方法不僅麻煩,而且也不是長久之計,還是存在失效的可能的。

          3. 新姿勢:用Python寫好的API工具超方便下載論文

          這是一個來自github的開源非官方API工具,下載地址為:
          https://github.com/zaytoun/scihub.py

          但由于作者長久不更新,原始的下載工具已經無法使用,Python實用寶典修改了作者的源代碼,適配了中文環(huán)境的下載器,并添加了異步批量下載等方法:
          https://github.com/Ckend/scihub-cn

          解壓下載的壓縮包后,使用CMD/Terminal進入這個文件夾,輸入以下命令(默認你已經安裝好了Python)安裝依賴:

          pip install -r requirements.txt

          然后我們就可以準備開始使用啦!

          這個工具使用起來非常簡單,有兩種方式,第一種方式你可以先在 Google 學術(搜索到論文的網(wǎng)址即可)或ieee上找到你需要的論文,復制論文網(wǎng)址如:

          http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=1648853

          ieee文章

          然后在scihub文件夾的scihub里新建一個文件叫download.py, 輸入以下代碼:

          from?scihub import?SciHub

          sh = SciHub()

          # 第一個參數(shù)輸入論文的網(wǎng)站地址
          # path: 文件保存路徑
          result = sh.download('http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=1648853', path='paper.pdf')


          進入該文件夾后在cmd/terminal中運行:

          python download.py


          你就會發(fā)現(xiàn)文件成功下載到你的當前目錄啦,名字為paper.pdf如果不行,多試幾次就可以啦,還是不行的話,可以在下方留言區(qū)詢問哦。

          上述是第一種下載方式,第二種方式你可以通過在知網(wǎng)或者百度學術上搜索論文拿到DOI號進行下載,比如:

          將DOI號填入download函數(shù)中:

          from?scihub import?SciHub
          sh = SciHub()
          result = sh.download('10.1016/j.compeleceng.2020.106640', path='paper2.pdf')


          下載完成后就會在文件夾中出現(xiàn)該文獻:



          2020-06-25新增:基于關鍵詞的論文批量下載

          今天更新了一波接口,現(xiàn)在支持使用搜索的形式批量下載論文,比如說搜索關鍵詞?端午節(jié)(Dragon Boat Festival):

          from?scihub import?SciHub
          sh = SciHub()

          # 搜索詞
          keywords = "Dragon Boat Festival"
          # 搜索該關鍵詞相關的論文,limit為篇數(shù)
          result = sh.search(keywords, limit=10)
          print(result)

          for?index, paper in?enumerate(result.get("papers", [])):
          ????# 批量下載這些論文
          ????sh.download(paper["url"], path=f"files/{keywords.replace(' ', '_')}_{index}.pdf")


          運行結果,下載成功:


          2021-01-07 異步下載優(yōu)化,增加超時控制

          這個開源代碼庫已經運行了幾個月,經常有同學反饋搜索論文后下載論文的速度過慢、下載的文件損壞的問題,這幾天剛好有時間一起解決了。

          下載速度過慢是因為之前的版本使用了串行的方式去獲取數(shù)據(jù)和保存文件,事實上對于這種IO密集型的操作,最高效的方式是用 asyncio 異步的形式去進行文件的下載。

          而下載的文件損壞則是因為下載時間過長,觸發(fā)了超時限制,導致文件傳輸過程直接被腰斬了。

          因此,我們將在原有代碼的基礎上添加兩個方法:1.異步請求下載鏈接,2.異步保存文件。

          此外增加一個錯誤提示:如果下載超時了,提示用戶下載超時并不保存損壞的文件,用戶可自行選擇調高超時限制。

          首先,新增異步獲取scihub直鏈的方法,改為異步獲取相關論文的scihub直鏈:

          async?def?async_get_direct_url(self, identifier):
          ????"""
          ????異步獲取scihub直鏈
          ????"""

          ????async?with?aiohttp.ClientSession() as?sess:
          ????????async?with?sess.get(self.base_url + identifier) as?res:
          ????????????logger.info(f"Fetching {self.base_url + identifier}...")
          ????????????# await 等待任務完成
          ????????????html = await?res.text(encoding='utf-8')
          ????????????s = self._get_soup(html)
          ????????????iframe = s.find('iframe')
          ????????????if?iframe:
          ????????????????return?iframe.get('src') if?not?iframe.get('src').startswith('//') \
          ????????????????????else?'http:'?+ iframe.get('src')
          ????????????else:
          ????????????????return?None


          這樣,在搜索論文后,調用該接口就能獲取所有需要下載的scihub直鏈,速度很快:

          def?search(keywords: str, limit: int):
          ????"""
          ????搜索相關論文并下載

          ????Args:
          ????????keywords (str): 關鍵詞
          ????????limit (int): 篇數(shù)
          ????"""


          ????sh = SciHub()
          ????result = sh.search(keywords, limit=limit)
          ????print(result)

          ????loop = asyncio.get_event_loop()
          ????# 獲取所有需要下載的scihub直鏈
          ????tasks = [sh.async_get_direct_url(paper["url"]) for?paper in?result.get("papers", [])]
          ????all_direct_urls = loop.run_until_complete(asyncio.gather(*tasks))
          ????print(all_direct_urls)



          獲取直鏈后,需要下載論文,同樣也是IO密集型操作,增加2個異步函數(shù):

          async?def?job(self, session, url, destination='', path=None):
          ????"""
          ????異步下載文件
          ????"""

          ????file_name = url.split("/")[-1].split("#")[0]
          ????logger.info(f"正在讀取并寫入 {file_name}?中...")
          ????# 異步讀取內容
          ????try:
          ????????url_handler = await?session.get(url)
          ????????content = await?url_handler.read()
          ????except:
          ????????logger.error("獲取源文件超時,請檢查網(wǎng)絡環(huán)境或增加超時時限")
          ????????return?str(url)
          ????with?open(os.path.join(destination, path + file_name), 'wb') as?f:
          ????????# 寫入至文件
          ????????f.write(content)
          ????return?str(url)

          async?def?async_download(self, loop, urls, destination='', path=None):
          ????"""
          ????觸發(fā)異步下載任務
          ????如果你要增加超時時間,請修改 total=300
          ????"""

          ????async?with?aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=300)) as?session:
          ????????# 建立會話session
          ????????tasks = [loop.create_task(self.job(session, url, destination, path)) for?url in?urls]
          ????????# 建立所有任務
          ????????finished, unfinished = await?asyncio.wait(tasks)
          ????????# 觸發(fā)await,等待任務完成
          ????????[r.result() for?r in?finished]


          最后,在search函數(shù)中補充下載操作:

          import?asyncio
          from?scihub import?SciHub


          def?search(keywords: str, limit: int):
          ????"""
          ????搜索相關論文并下載

          ????Args:
          ????????keywords (str): 關鍵詞
          ????????limit (int): 篇數(shù)
          ????"""


          ????sh = SciHub()
          ????result = sh.search(keywords, limit=limit)
          ????print(result)

          ????loop = asyncio.get_event_loop()
          ????# 獲取所有需要下載的scihub直鏈
          ????tasks = [sh.async_get_direct_url(paper["url"]) for?paper in?result.get("papers", [])]
          ????all_direct_urls = loop.run_until_complete(asyncio.gather(*tasks))
          ????print(all_direct_urls)

          ????# 下載所有論文
          ????loop.run_until_complete(sh.async_download(loop, all_direct_urls, path=f"files/"))
          ????loop.close()


          if?__name__ == '__main__':
          ????search("quant", 5)


          一個完整的下載過程就OK了:



          比以前的方式舒服太多太多了... 如果你要增加超時時間,請修改async_download函數(shù)中的 total=300,把這個請求總時間調高即可。

          最新代碼前往GitHub上下載:
          https://github.com/Ckend/scihub-cn

          4.工作原理

          這個API的源代碼其實非常好讀懂

          4.1、找到sci-hub目前可用的域名

          首先它會在這個網(wǎng)址里找到sci-hub當前可用的域名,用于下載論文:

          https://whereisscihub.now.sh/


          可惜的是,作者常年不維護,該地址已經失效了,我們就是在這里修改了該域名,使得項目得以重新正常運作:

          4.2、對用戶輸入的論文地址進行解析,找到相應論文

          1. 如果用戶輸入的鏈接不是直接能下載的,則使用sci-hub進行下載

          2. 如果scihub的網(wǎng)址無法使用則切換另一個網(wǎng)址使用,除非所有網(wǎng)址都無法使用。


          3.值得注意的是,如果用戶輸入的是論文的關鍵詞,我們將調用sciencedirect的接口,拿到論文地址,再使用scihub進行論文的下載。

          4.3、下載

          1. 拿到論文后,它保存到data變量中

          2. 然后將data變量存儲為文件即可


          此外,代碼用到了一個retry裝飾器,這個裝飾器可以用來進行錯誤重試,作者設定了重試次數(shù)為10次,每次重試最大等待時間不超過1秒。

          希望大家能妥善使用好此工具,不要批量下載,否則一旦網(wǎng)站被封,學生黨們又要哭了。

          我們的文章到此就結束啦,如果你喜歡今天的Python 實戰(zhàn)教程,請持續(xù)關注Python實用寶典。

          下載:https://github.com/Ckend/scihub-cn

          瀏覽 29
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  高清无码三级片 | 天堂无码视频在线播放 | 天天综合7799精品视频 | 猫咪AV大香蕉 | 麻豆久久久久久 |