1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        支持百度學(xué)術(shù)搜索!Python文獻超級搜索下載工具又更新了!

        共 10838字,需瀏覽 22分鐘

         ·

        2021-05-20 17:21

        文獻搜索對于廣大學(xué)子來說真的是個麻煩事 ,如果你的學(xué)校購買的論文下載權(quán)限不夠多,或者你不在校園網(wǎng)覆蓋的范圍內(nèi),想必會令你非常頭痛。
        幸好,我們有Python制作的這個論文搜索工具,簡化了我們學(xué)習(xí)的復(fù)雜性

        更新日志:

        2020-05-28補充:已用最新的scihub提取網(wǎng),目前項目可用,感謝@lisenjor的分享。

        2020-06-25補充:增加關(guān)鍵詞搜索,批量下載論文功能。

        2021-01-07補充:增加異步下載方式,加快下載速度;加強下載穩(wěn)定性,不再出現(xiàn)文件損壞的情況。

        2021-04-08補充:由于sciencedirect增加了機器人檢驗,現(xiàn)在搜索下載功能需要先在HEADERS中填入Cookie才可爬取,詳見第4步。

        2021-04-25補充:搜索下載增加百度學(xué)術(shù)、publons渠道。

        本文完整源代碼可在 GitHub 找到:

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


        1. 什么是Scihub

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


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

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

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

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

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

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

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

        歡迎給我一個Star,鼓勵我繼續(xù)維護這個倉庫。如果你訪問不了GitHub,請在 Python實用寶典 公眾號后臺回復(fù) scihub,下載最新可用代碼。

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

        pip install -r requirements.txt

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

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

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

        ieee文章

        然后在scihub-cn文件夾里新建一個文件叫 my_test.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 my_test.py


        你就會發(fā)現(xiàn)文件成功下載到你的當(dāng)前目錄啦,名字為paper.pdf如果不行,有可能是網(wǎng)絡(luò)問題,多試幾次。實在不行可以在下方留言區(qū)詢問哦。

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

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

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


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



        除了這種最簡單的方式,我們還提供了 論文關(guān)鍵詞搜索批量下載 及 論文關(guān)鍵詞批量異步下載 兩種高級的下載方法。

        我們在下文將會詳細地講解這兩種方法的使用,大家可以看項目內(nèi)的  test.py 文件,你可以了解到論文搜索批量下載的方法。

        進一步的高級方法在download.py 中可以找到,它可以實現(xiàn)論文搜索批量異步下載,大大加快下載速度。具體實現(xiàn)請看后文。

        4. 基于關(guān)鍵詞的論文批量下載

        支持使用搜索的形式批量下載論文,比如說搜索關(guān)鍵詞 端午節(jié)(Dragon Boat Festival):

        from scihub import SciHub
        sh = SciHub()

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

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


        默認會使用百度學(xué)術(shù)進行論文搜索,拿到DOI號后再通過scihub下載,運行成功:

        2021-04-25 更新:

        由于讀者們覺得Sciencedirect的搜索實在太難用了,加上Sciencedirect現(xiàn)在必須要使用Cookie才能正常下載,因此我新增了百度學(xué)術(shù)和publons這2個檢索渠道。

        由于 Web of Science 有權(quán)限限制,很遺憾我們無法直接使用它來檢索,不過百度學(xué)術(shù)作為一個替代方案也是非常不錯的。

        現(xiàn)在默認的 search 函數(shù)調(diào)用了百度學(xué)術(shù)的接口進行搜索,大家不需要配置任何東西,只需要拉一下最新的代碼,使用上述例子中的代碼就可以正常搜索下載論文。

        其他兩個渠道的使用方式如下:

        sciencedirect渠道:

        由于 sciencedirect 加強了他們的爬蟲防護能力,增加了機器人校驗機制,所以現(xiàn)在必須在HEADER中填入Cookie才能進行爬取。

        操作如下:

        1.獲取Cookie


        2.使用sciencedirect搜索時,需要用 search_by_science_direct 函數(shù),并將cookie作為參數(shù)之一傳入:

        from scihub import SciHub

        sh = SciHub()

        # 搜索詞
        keywords = "Dragon Boat Festival"

        # 搜索該關(guān)鍵詞相關(guān)的論文,limit為篇數(shù)
        result = sh.search_by_science_direct(keywords, cookie="你的cookie", limit=10)

        print(result)

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


        這樣大概率就能順利通過sciencedirect搜索并下載文獻了。

        publons渠道:

        其實有了百度學(xué)術(shù)的默認渠道,大部分文獻我們都能覆蓋到了。但是考慮到publons的特殊性,這里還是給大家一個通過publons渠道搜索下載的選項。

        使用publons渠道搜索下載其實很簡單,你只需要更改搜索的函數(shù)名即可,不需要配置Cookie:

        from scihub import SciHub

        sh = SciHub()

        # 搜索詞
        keywords = "Dragon Boat Festival"

        # 搜索該關(guān)鍵詞相關(guān)的論文,limit為篇數(shù)
        result = sh.search_by_publons(keywords, limit=10)

        print(result)

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


        5. 異步下載優(yōu)化,增加超時控制

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

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

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

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

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

        首先,新增異步獲取scihub直鏈的方法,改為異步獲取相關(guān)論文的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 等待任務(wù)完成
                    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


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

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

            Args:
                keywords (str): 關(guān)鍵詞
                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["doi"]) 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} 中...")
            # 異步讀取內(nèi)容
            try:
                url_handler = await session.get(url)
                content = await url_handler.read()
            except:
                logger.error("獲取源文件超時,請檢查網(wǎng)絡(luò)環(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ā)異步下載任務(wù)
            如果你要增加超時時間,請修改 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]
                # 建立所有任務(wù)
                finished, unfinished = await asyncio.wait(tasks)
                # 觸發(fā)await,等待任務(wù)完成
                [r.result() for r in finished]


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

        import asyncio
        from scihub import SciHub


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

            Args:
                keywords (str): 關(guān)鍵詞
                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["doi"]) 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,把這個請求總時間調(diào)高即可。

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

        6.工作原理

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

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

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

        https://whereisscihub.now.sh/


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

        6.2、對用戶輸入的論文地址進行解析,找到相應(yīng)論文

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

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


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

        6.3、下載

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

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


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

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

        -end-

        瀏覽 58
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

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

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产乱伦免费视频 | 水多多成人精品视频 | 国产av一区二区三区 | 四虎成人精品A片 | 国产福利午夜在线观看 | 动漫美女被狂揉下部网站 | 无码任你躁久久久久久在少妇 | 激情久久婷婷 | 豆花视频九九九 | 一级片乱伦 |