3atv精品不卡视频,97人人超碰国产精品最新,中文字幕av一区二区三区人妻少妇,久久久精品波多野结衣,日韩一区二区三区精品

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

【Python爬虫】从零开始爬取Sci-Hub上的论文(串行爬取)

發布時間:2023/12/15 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Python爬虫】从零开始爬取Sci-Hub上的论文(串行爬取) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【Python爬蟲】從零開始爬取Sci-Hub上的論文(串行爬取)

  • 維護日志
  • 項目簡介
  • 步驟與實踐
    • STEP1 獲取目標內容的列表
    • STEP2 利用開發者工具進行網頁調研
      • 2.1 提取文章鏈接和分頁鏈接的特征
      • 2.2 提取文章 DOI 所在元素的特征
      • 2.3 探索 sci-hub 上 pdf 資源的打開方式
        • 2.3.1 梳理基本流程
        • 2.3.2 查看 robots.txt
        • 2.3.3 提取pdf資源的元素特征
    • STEP3 開始寫代碼,就從"下載"入手吧
      • 3.1 conda虛擬環境搭建、加載和使用
        • 3.1.1 創建虛擬環境
        • 3.1.2 配置下載包的鏡像源
        • 3.1.3 給虛擬環境安裝所需模塊
        • 3.1.4 加載虛擬環境到我們的 IDE —— PyCharm
      • 3.2 下載一個pdf文獻的代碼實現
        • 3.2.1 用 requests 根據 DOI 獲取文獻對應網頁的文本
        • 3.2.2 提取 html 中的 pdf 資源鏈接 (3種方式)
          • 正則表達式 (Regular Expression)
          • Beautiful Soup
          • Lxml ?\star?
            • 在瀏覽器控制臺中使用選擇器
            • 在代碼中使用選擇器
        • 3.2.3 根據獲得的 pdf 鏈接執行下載
        • 3.2.4 看看哪些地方仍需改進
          • 磁盤文件合法命名
          • 獲得文件所需的名稱 —— 文獻標題
          • robots.txt 解析以及下載時間間隔設置
          • 添加一個簡單的緩存類 Cache
      • 3.3 回到 Web of Science,提取搜索頁的 DOI 列表
        • 3.3.1 方法一:修改 doc 屬性值快速構建 url,然后從中爬取 doi
        • 3.3.2 方法二:結合 Web of Science 導出功能的"零封禁幾率"方法
    • STEP4 組裝起來,形成終極接口:sci_spider()
      • 4.1 流程梳理 ?\star?
      • 4.2 組裝起來,給它取個名字,就叫 "sci_spider" 好了
      • 4.3 對第一次運行結果的分析與問題處理 ?\star?
        • 4.3.1 運行結果分析
        • 4.3.2 問題1:標題抓取為空 —— 用 DOI 作為名字
        • 4.3.3 問題2:HTTP協議頭重復 —— 添加判斷去重
        • 4.3.4 最后的調試
  • 爬蟲感想
  • 資源 (見GitHub)
  • References

WARNING:專業人士請速速撤離,否則將浪費至少半小時的時間!

2020-12-06 陰


是時候上手鴿了半個月的小項目了。。。

筆者為了偷懶,準備邊做爬蟲邊記錄過程,畢竟做完后還要花很多時間回顧,這里就直接省去回顧的過程,每完成一個步驟便做好相應的步驟記錄。當你讀到這段文字時,筆者尚未開始進行這個項目的實踐,但也并非完全"從零開始" —— 在此之前筆者學了一些爬蟲相關的先修知識,并作了實踐環境和工具的一些配置,具體如下:

★\bigstar 先修知識 (每一項筆者都附上了教程鏈接,如有需要可以點擊查看)

  • Web基礎 (html5,只需看得懂網頁層級結構和標簽屬性含義即可) →\rightarrow 點擊查看 html 基礎教程

  • 正則表達式 (能看懂并構建簡單的表達式) →\rightarrow 點擊查看正則表達式基礎教程

  • Python3 基礎語法 (能編寫函數和類,懂列表、字典等經典數據結構的操作) →\rightarrow 點擊回顧 Python3 基礎知識

  • 爬蟲的基本操作 (對應文獻1的前三章 [1])

  • 網頁調研 (了解html文本結構,分析元素特征,查看網頁的 robots.txt 獲取爬取的基本要求)

  • 數據抓取 (獲取html文本中的目標內容,如 url,列表項內容等,常用的方式有:① 正則表達式;② BeautifulSoup;③ Lxml 以及CSS選擇器和Xpath選擇器)

  • 下載緩存 (這個項目可能用不到 )

★\bigstar 工具與環境

  • 語言版本:Python3.6 (這個安裝就不用我多說了吧,網上搜一下就有)

  • IDE:PyCharm Community Edition 2019.3.3 (同上)

  • 虛擬環境管理:Anaconda3 →\rightarrow 點此查看 ① PyCharm加載和使用虛擬環境;②conda環境管理

    注:如果不清楚虛擬環境的意義,可以自行搜索了解,簡單來說就是為爬蟲用到的庫單獨創建一個容器,與爬蟲相關的模塊都放在這里,以防止各模塊版本錯亂,導致用 Python3 寫的其余項目因版本問題出現錯誤。

好了,有了以上準備,我們就可以真正地"從零開始"我們的爬蟲之旅了!

維護日志

爬蟲代碼是很不穩定的,當爬取目標發生變化時,原來的代碼很可能就不能運行了,因此讀者應盡可能地掌握爬蟲實踐的方法,這樣便可以通過修改代碼來應對新的變化。

2021-09-24 爬蟲代碼ver2.1
上傳了version2.1版本,修復了兩個錯誤:

  • error - list index out of range: 這是由于pdf文獻的url在網頁中的標簽層次不一致所致,有些為buttons/button,還有些為buttons/ul/li/a,而以往代碼只考慮了其中一種層次,解決方法是兩種情況全部考慮(不排除還有其他的層次),篩選列表不為空的即可。

  • error - Invalid URL: 調用requests.get(url, …)時,有些url中存在轉義字符’’,比如https:\/\/sci.bban.top\/pdf\/10.1145\/3132847.3132909.pdf?download=true,導致get()方法誤認為’‘需要轉義,從而額外添加轉義字符’’,使得上述url變為https:\\/\\/sci.bban.top\\/pdf\\/10.1145\\/3132847.3132909.pdf?download=true,因而出錯。解決方法是,在GET請求前去掉url中的轉義字符’’。

  • 2021-08-05 爬蟲代碼ver2.0

  • web-of-science不能導出html文件了,因此現通過導出的txt文本,結合正則表達式來抓取doi列表
  • sci-hub輸入doi后的文獻頁面,pdf下載鏈接所在的標簽層次和類型有所變化:從<a>變為了<button>,且少了一些層次,這導致原本的xpath篩選模式不可用
  • pdf存儲路徑可以修改(通過調整sci_spider(…)函數的dir參數)
  • 代碼可以通過私信向筆者索要,或者關注筆者的github自行獲取,請使用最新版。


    項目簡介

    開始構建爬蟲之前,首先明確我們的需求:根據搜索文本從sci-hub上爬取論文(pdf格式),具體方式是:

  • 在 Web-of-Science 網站上輸入搜索文本,執行搜索后獲取每一項搜索結果的 DOI (Digital Object Identifier,數字對象唯一標識)

  • 根據得到的 DOI,依次在 Sci-Hub 上查找到論文資源并下載

  • 當然,上述描述是可行的 (手動操作),但現在我們要通過爬蟲來實現"無UI交互",即通過代碼而不是人為瀏覽網頁的方式達到目的。為此,需要細化以上過程的描述,這個過程筆者是邊想邊做的,當實現所有的描述時,任務也就完成了。

    步驟與實踐

    先附上項目涉及的兩個主要網站:

    • Web of Science: http://apps.webofknowledge.com

    • Sci-Hub: https://sci-hub.do/ (這個經常被封禁,如果用不了可以上網搜其他的域名)

    補充:筆者使用的瀏覽器是Google Chrome,其實用哪個瀏覽器都行,只要能正常訪問網頁,且瀏覽器有開發者工具(按F12調出)即可。

    STEP1 獲取目標內容的列表

    由用戶手動在 Web-of-Science 上搜索某一內容(這里采用主題模式,搜索 “unity3D”),獲得相應的列表,如下圖所示:

    注意:

  • 搜索結果后面顯示了查詢結果個數,我們可以根據它來決定下載文件的數量

  • 有一些是專利發表,不包含 DOI (如上圖第2項),不過只要我們的爬蟲不會錯誤地訪問并下載它們就行

  • STEP2 利用開發者工具進行網頁調研

    對產生列表的網頁進行html文本特征分析,發現列表每一項中并沒有列出 DOI,這意味著兩件事:

    • 我們需要存儲列表網頁中的目標url (用一個列表結構存儲),由于搜索結果可能不止一頁,因此,我們保存的 url 中應既包括文章鏈接,也包括分頁鏈接 (其他鏈接就不考慮了)。

    • 我們需要訪問每一個 url 列表中的鏈接,找到 DOI 所在的標簽,分析其所在的嵌套層級以及它本身的特征 (標簽的特征屬性,如 ”href“、“id”、“class” 等),并把所有 DOI 也保存到一個列表中,甚至可以將它存到磁盤 (例如以 .csv 或 .txt 格式保存)。

    先吃個飯,然后分析一波目標url的特征以及DOI所在標簽的特征。。。

    2.1 提取文章鏈接和分頁鏈接的特征

    那么,文章鏈接和分頁鏈接怎么找呢?打開開發者工具(F12),使用 “選擇元素” 功能 (Shift + Ctrl + C)選定頁面中的目標元素,幫助我們縮小查找范圍,甚至直接定位鏈接。下面分別給出了針對文章鏈接和分頁鏈接的選擇元素圖例,以及各自的查找到的鏈接情況:

    下面是找到的目標區域鏈接,依次為 文章鏈接 和 分頁鏈接:

    <a class="smallV110 snowplow-full-record" href="/full_record.do?product=UA&amp;search_mode=GeneralSearch&amp;qid=2&amp;SID=7ERiKiVBBTB6qFk3KUC&amp;page=1&amp;doc=1" tabindex="0" oncontextmenu="javascript:return IsAllowedRightClick(this);" hasautosubmit="true"> <value lang_id="">Implementing Virtual Reality technology for safety training in the precast/prestressed concrete industry</value> </a> <a class="paginationNext snowplow-navigation-nextpage-bottom" href="http://apps.webofknowledge.com/summary.do?product=UA&amp;parentProduct=UA&amp;search_mode=GeneralSearch&amp;parentQid=&amp;qid=2&amp;SID=7ERiKiVBBTB6qFk3KUC&amp;&amp;update_back2search_link_param=yes&amp;page=2" alt="下一頁" title="下一頁" aria-label="下一頁" tabindex="0" oncontextmenu="javascript:return IsAllowedRightClick(this);" hasautosubmit="true"> <i></i> </a>

    為了提取特征,筆者額外找了幾個不同文獻和不同分頁的鏈接,發現了一些共同點,它們正是我們做爬蟲的重要依據:

  • 每一個文章鏈接都在 <a> 標簽的 href 屬性中,且標簽 class 相同,均為 "smallV110 snowplow-full-record" ;分頁鏈接的 class="paginationNext snowplow-navigation-nextpage-bottom"

  • 觀察 url 本身,發現 文章鏈接 的 url 是個相對url,/full_record.do?... 打頭,如果手動點擊進入的話其鏈接為 http://apps.webofknowledge.com/full_record.do?...;而 分頁鏈接 的 url 是個絕對url,鏈接為 http://apps.webofknowledge.com/summary.do?product...,我們需要的是絕對url,這說明我們對于 文章鏈接 還需要額外處理,加上 http://apps.webofknowledge.com 這一部分。

  • 由于 文章鏈接 和 分頁鏈接 的處理模式存在區別,而它們的 class 屬性不同,因此我們可以創建兩個隊列,利用 class 屬性區分兩種鏈接,分別加入到相應的隊列中,并且優先處理文章鏈接所在的隊列,這意味著當且僅當文章鏈接的隊列為空時,才會處理分頁鏈接的隊列。然而,還有更簡單且高效的方法,不用一個個請求網頁的內容,沒有IP封禁的危險 (見 3.3 節)。

    2.2 提取文章 DOI 所在元素的特征

    下面我們把目光聚焦到 文章鏈接 打開的頁面,找尋文章的DOI,其操作和上一節的一樣。僅陳列頁面布局和目標元素內容:

    <div class="block-record-info"> <p class="FR_field"> ... </p> </div> <div class="block-record-info-source-values"> ... <p class="FR_field"> <span class="FR_label">文獻號:</span> <value>103286</value> </p> <p class="FR_field"> <span class="FR_label">DOI:</span> <value>10.1016/j.apergo.2020.103286</value> </p> ... </div>

    通過對其父級標簽 <p class="FR_field"> 比對發現,它并不能區分DOI和其余同級內容。另外,在其所屬的 <div> 標簽的同級標簽中,也存在一些標簽含有 <p class="FR_field">,這意味著我們可能需要分層篩選,但我們也可以簡單粗暴直接匹配到 DOI,方法和細節稍后提及。

    如此一來,我們便可以輕松獲得多個文獻的 DOI,并把它們存放于一個列表中,甚至寫入磁盤文件。

    2.3 探索 sci-hub 上 pdf 資源的打開方式

    2.3.1 梳理基本流程

    假定我們已經有一個十分有效的方式得到合法的 DOI 列表 (然而現在我們并沒有),那么下一步就是將 sci-hub 的手動下載模式轉換為程序控制的批量作業。為此我們得先摸清手動操作是怎么個流程:

  • 將目標文獻的 DOI 復制到搜索框,然后點擊大大的 open 按鈕,在此之前鏈接為 http(s)://sci-hub.do
  • 然后,我們觀察到網址變為了 http(s)://sci-hub.do/10.1016/j.apergo.2020.103286,僅僅這一個DOI我們便能斷言:資源鏈接的格式為 http(s)://sci-hub.do/{DOI}
  • wtf,校園網連接沒有響應,訪問不了 sci-hub 資源鏈接。。。那我先看會書,等回宿舍后再接著做吧

    2.3.2 查看 robots.txt

    可能是今天網絡問題 (事實上當時 sci-hub 在維護中),使得我無法通過輸入 DOI 來訪問 sci-hub 相應資源,不過沒關系,我們先看看 sci-hub 的 robots.txt 文件 (主頁域名后面加個 /robots.txt 即可):

    User-agent: Twitterbot Disallow:User-agent: * Allow: /lang/ Allow: /alexandra Allow: /$ Disallow: /

    這個文件是一個非強制性的協議,每個良好的網絡公民都應該遵守這些限制,否則有可能遭到封禁。該文件的解讀方法 →\rightarrow 爬蟲之robots.txt

    從該文件的內容可知,第一部分:該網頁允許用 Twitterbot 作為用戶代理爬取該網站上的任何東西 (更正,經筆者測試,如果用 Twitterbot 作為用戶代理抓取網頁,那么似乎會重定向,讓你抓取其他網頁的內容,所以不要用 Twitterbot ) ;第二部分:對所有用戶代理都有效,但只允許了部分網站的爬取,那個 /$ 按照解釋應該為允許任何以 / 結尾的 url (更正,似乎也不太對,只要不是 sci-hub 主頁,即便沒有以 / 結尾也可以抓取) 。

    以上解釋和實際的解析有些出入,筆者拿學習爬蟲時做的 robots.txt 解析代碼試了一下,發現 Twitterbot 的爬取不受任何限制, 其余用戶代理除了主頁不能爬取外,其余都能爬。不過,誰來 sci-hub 是為了爬取主頁呀? 所以說,基本沒有限制,我們可以"橫著走"。

    (應該說只要用戶代理不是 Twitterbot,那我們便可以"橫著走"。)

    2020-12-07 雪


    2.3.3 提取pdf資源的元素特征

    我們隨便找個文獻的DOI,請求相應的鏈接。試了好久,終于成功進去了!!(薛定諤的網絡連接)

    審查網頁中 save 按鈕,定位其標簽在超文本中的位置:

    <div id="buttons"> <ul> <!-- <li id = "reload"><a target = "_blank" href = "//sci-hub.do/reload/10.1016/j.apergo.2020.103286">? reload</a></li>--> <li><a href="#" onclick="location.href='//sci-hub.do/downloads/2020-12-01/29/joshi2021.pdf?download=true'">? save</a></li> </ul> </div>

    我們注意 <a> 標簽中的 onclick 屬性內容,將 location.href 單引號中的內容擰出來,很容易發現:如果在前面加個 http(s):,那么就構成了絕對 url,直接把加了 http(s): 的上述內容 cv 到域名搜索框中,看看能否彈出下載頁面 —— 實踐告訴我們,輸入后直接鏈接到了 pdf 資源,并自動開始了下載!(來自未來:這里筆者當時并沒有考慮 HTTP協議頭可能重復的問題)

    太好了!這樣我們的一輪流程就走完了,剩下的都是重復的迭代過程,就交給計算機處理了。因此,現在我們可以順著以上的思路寫代碼了。

    STEP3 開始寫代碼,就從"下載"入手吧

    再次提一下,我們最終的期望是實現批量 pdf 下載,可見"下載"是我們的關鍵步驟(之一)。當我們的流水線到達下載這一步時,我們已經獲得了一個 DOI 列表,我們需要根據這個 DOI 列表中的每一項來依次執行下載任務,2.3.3 節已經分析了 pdf 資源鏈接的構成,即 HTTP協議 + 冒號’:’ + location.href 的內容,最后一部分是從鏈接{ 'http(s)://sci-hub.do' + '/' + DOI }對應的 html 中抓取的。思路有了,我們如果能實現一個文件的下載,那么批量下載無非就是加了個循環 (暫不涉及多線程)。但在此之前,為了符合"從零開始",我還是從搭建環境開始簡單地演示一遍吧。

    3.1 conda虛擬環境搭建、加載和使用

    可以跳過這部分內容 —— 虛擬環境不是必要的但當你有多個項目正在開發時,虛擬環境可以有效管理安裝包的版本,避免混亂。

    現在筆者手上已有 PyCharm (ver 2019.3.3) 以及 Anaconda 3,使用的 Python3 版本為 3.6,OS 為 Win10。

    我想你應該已經把 Python 語言以及 Anaconda 的環境變量配置好了,如果不確定的話可以查看 Path 變量中是否包括如下路徑:

    • Python3 安裝根目錄下的Scripts文件夾所在路徑,e.g: D:\…\Scripts

    • Anaconda 安裝根目錄下Scripts文件夾所在路徑,e.g: E:\…\Anaconda\Scripts

    3.1.1 創建虛擬環境

    首先找到 Anaconda Prompt (筆者直接在開始菜單 'A’字母中的 Anaconda文件夾下找到),打開后如下:

    輸入 conda create -n <虛擬環境名> python=<版本號> 創建環境 (筆者用的Python的版本號為3.6)。比如下圖中,筆者創建了名為 Python36_WebCrawler 的虛擬環境,過程中等待片刻后需要按個確認按鈕:

    至此,虛擬環境安裝完畢,我們本次項目要用到的所有包都放在這個環境中。

    3.1.2 配置下載包的鏡像源

    一般使用的是清華鏡像源,里面有大量的包,我們可以按需從鏡像源獲取模塊。

    如果你已經配置過,那么不論之后是否創建新的虛擬環境,你都無需再配置了

    鍵入如下指令添加鏡像源 (注意:HTTP協議不要用 https,否則有可能出現問題;另外,你的鍵入順序就是搜索包的路徑順序,所以可以預先調研一波 —— 你所需要的包大多數在哪個目錄下,那么就把該目錄放在最前面)

    conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/win-64/ conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/win-64/ conda config --set show_channel_urls yes

    如果你用的是其他操作系統,可能需要更改一波鏡像源路徑,具體可以去清華鏡像站查看目錄層級,比如修改 /win-64。

    這樣我們就可以在 C:\Users\Administrator 下找到一個 .condarc,用記事本打開可以查看我們的設置:

    下載源設置好了,下面我們可以安裝包了。

    3.1.3 給虛擬環境安裝所需模塊

    我們來安裝待會要用到的 requests 模塊。

    • 回到 Anaconda Prompt,輸入 conda activate <你的虛擬環境名> 激活環境,光標跳轉到 (Python36_WebCrawler) C:\Users\Administrator>

    • 輸入 conda install requests,找到下載源和相應版本后 (可能還附帶該模塊的依賴項),出現確認事件 Proceed ([y]/n)?,回車默認 yes,畫面如下:

    至此,requests 模塊安裝完畢,我們鍵入 conda deactivate 退出 Python36_WebCrawler 環境。

    之后所有的包都是這么個安裝流程:激活環境 →\rightarrow 安裝包 →\rightarrow 退出環境。

    3.1.4 加載虛擬環境到我們的 IDE —— PyCharm

    如果讀者用的是其他 IDE,沒有關系,網上有很多介紹如何將虛擬環境加載到 IDE 的資料。筆者這里也不再贅述,僅給個PyCharm使用虛擬環境的鏈接 —— PyCharm加載和使用虛擬環境。

    3.2 下載一個pdf文獻的代碼實現

    如果您是從頭開始讀到這里,那么,在這里說聲,幸苦了!表面上看,我們的征途才剛剛開始,但筆者認為,現在已經快結束了 (可能有些夸張 (來自未來:太TM夸張了),但至少已經完成一半的工作了 (來自未來:這倒是沒錯))。后續基本上是代碼的實踐與細節,每一個步驟,筆者會先上代碼,然后簡要分析一下:①代碼干了什么;②為什么這么寫?

    至于里面用到的一些模塊函數的用法,我確定您是知道的 (至少有兩種辦法知道,其中一個方法是查看模塊源文件;另一個是上網搜索解決方案)。因此筆者就偷個懶,省去一些功夫去解析它們 —— 我們這里更強調對模塊函數的使用,了解接口的功能和用法就好了 (在PyCharm中,只需要把光標放在相應函數上,Ctrl + 鼠標左鍵 即可查看相應的函數定義)。

    3.2.1 用 requests 根據 DOI 獲取文獻對應網頁的文本

    下面我們直接給出 獲取特定 DOI 網頁超文本 的 Python3 實現 (download.py):

    import requestsdef download(doi, user_agent="sheng", proxies=None, num_retries=2, start_url='sci-hub.do'):headers = {'User-Agent': user_agent}url = 'https://{}/{}'.format(start_url, doi)print('Downloading: ', url)try:resp = requests.get(url, headers=headers, proxies=proxies, verify=False)html = resp.textif resp.status_code >= 400:print('Download error: ', resp.text)html = Noneif num_retries and 500 <= resp.status_code < 600:return download(url, user_agent, proxies, num_retries-1)except requests.exceptions.RequestException as e:print('Download error', e)return Nonereturn html# 簡單的測試 if __name__ == '__main__':doi = '10.1016/j.apergo.2020.103286'print(download(doi))print('Done.')

    運行結果:

    Downloading: https://sci-hub.do/10.1016/j.apergo.2020.103286 # 拼接好的 DOI 文獻鏈接 D:\...\connectionpool.py:852: InsecureRequestWarning: ... # 一個警告,可以忽略,這與我們設置vertify=False有關 <html> # 我們要的超文本 ... </html> Done.

    對代碼的說明:

  • 簡析一下函數原型:def download(doi, user_agent="sheng", proxies=None, num_retries=2, start_url='sci-hub.do'):

  • doi →\rightarrow 文獻的DOI號

  • user_agent →\rightarrow 用戶代理,根據sci-hub主頁的 robots.txt 確定,默認值只要不是 Twitterbot 就行

  • proxies →\rightarrow 代理,默認置為 None

  • num_retries →\rightarrow 下載的重試次數,僅當請求狀態碼為 5xx 時執行重試,像 4xx 之類的就沒必要重試了

  • start_url →\rightarrow 主頁域名,絕對路徑中固定的一部分,單獨擰出來,默認為 sci-hub.do (其他能用的也行)

  • 因此簡要概括這個函數的功能:根據傳入的 DOI 號,抓取所在文獻的 html 文本,以供后續提取 .pdf 文件鏈接。

  • 請求訪問網站的關鍵函數: requests.get(...),必須傳入 url,其余都是可選的;為了讓我們的爬蟲請求網頁時能更加可靠 (更像個人,而不是機器),我們傳入額外參數 user-agent 和 proxies,前者構成請求時發送給瀏覽器的頭信息 headers,后者設置代理支持,默認設置為 None。

  • requests.get() 參數列表中的 verify=False 不能少,否則很有可能出現 SSL: CERTIFICATE_VERIFY_FAILED 的錯誤:

    Downloading: https://sci-hub.do/10.1016/j.apergo.2020.103286 Download error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:748) Done.
  • 3.2.2 提取 html 中的 pdf 資源鏈接 (3種方式)

    下載搞定了,意味著我們得到了文獻網頁的 html,它將作為提取pdf資源鏈接的輸入,也可稱作"原材料"。

    在 2.3.3 節我們已經大致分析了 pdf 資源鏈接的特征,我們的任務是從中找到一種模式 (pattern),它能較好地幫我們從冗長的 html 文本中篩選并匹配目標元素

    為了方便說明筆者后續的提取方法,把 2.3.3 節目標所在位置的文本再陳列一遍 (原汁原味,沒有任何修改,之前的為了美觀,把一些空行、空格去掉了):

    <div id="buttons"><ul><!-- <li id = "reload"><a target = "_blank" href = "//sci-hub.do/reload/10.1016/j.apergo.2020.103286">? reload</a></li>--><li><a href="#" onclick="location.href='//sci-hub.do/downloads/2020-12-01/29/joshi2021.pdf?download=true'">? save</a></li></ul></div>

    對比一下抓取到的 html 文本的相同部分:

    <div id = "buttons"><ul><!-- <li id = "reload"><a target = "_blank" href = "//sci-hub.do/reload/10.1016/j.apergo.2020.103286">? reload</a></li>--><li><a href = # onclick = "location.href='//sci-hub.do/downloads/2020-12-01/29/joshi2021.pdf?download=true'">? save</a></li></ul></div>

    我們由以上對比,我們可以發現兩者的一些共性和區別:

    • 各個標簽之間有可能有空行、空格,也可能沒有

    • 前者的 href="#" 和后者的 href = #,其中有兩處不同:① = 前后是否有空格; ② # 是否有引號。關于 2,這是因為 href="#" 有特殊意義。

    這些細微的點如果不注意,將令我們編寫正則表達式時吃盡苦頭 (反正筆者已經"吃飽了")。

    正則表達式 (Regular Expression)

    如果你能熟練運用正則表達式,相信你會有 “萬物皆可RegEx” 的信念,并且會更傾向于用它解決這類匹配問題 —— 即使它仍存在很多局限。如果想要了解它,筆者在文章開頭就已經給出了教程,這里再附個有關 Python中使用正則表達式 的鏈接。

    像筆者這種笨比,編寫的正則表達式又臭又長,且經常需要修改很多遍才能弄好,不過好在有正則表達式在線測試網站,大大提高了正則表達式的編寫效率。

    我們可以根據其中一篇文獻的下載鏈接來編寫正則表達式,然后隨機找幾篇文獻(不同領域)的下載鏈接對正則表達式驗證,如果測試的那些沒問題,我們就直接用吧。

    下面給出 用正則表達式匹配超文本以獲取匹配內容列表 的 Python3 實現 (scraping_using_regex.py):

    import redef get_links(pattern, html):regex = re.compile(pattern, re.IGNORECASE)return regex.findall(html)if __name__ == '__main__':from download import downloaddois = ['10.1016/j.apergo.2020.103286', # VR'10.1016/j.jallcom.2020.156728', # SOFC'10.3964/j.issn.1000-0593(2020)05-1356-06'] # 飛行器# 筆者又臭又長的正則表達式pattern = '''<div id\s*=\s*"buttons">\s*<ul>\s*.*?\s*<li.*?\s*<li><a[^>]+href\s*=\s*#\s*onclick\s*=\s*"location.href='(.*?)'">'''links = []for doi in dois:html = download(doi)# print(html)links.append(get_links(pattern, html))for link in links:print(link)

    運行結果:

    Downloading: https://sci-hub.do/10.1016/j.apergo.2020.103286 D:\Anaconda\...\connectionpool.py:852: InsecureRequestWarning:... Downloading: https://sci-hub.do/10.1016/j.jallcom.2020.156728 D:\Anaconda\...\connectionpool.py:852: InsecureRequestWarning:... Downloading: https://sci-hub.do/10.3964/j.issn.1000-0593(2020)05-1356-06 D:\Anaconda\...\connectionpool.py:852: InsecureRequestWarning:... # 我們獲取的 pdf 鏈接結果 ['//sci-hub.do/downloads/2020-12-01/29/joshi2021.pdf?download=true'] ['//sci-hub.do/downloads/2020-11-23/ac/tsvinkinberg2021.pdf?download=true'] []

    對代碼與結果的說明:

  • def compile() 將一個正則表達式轉變為 pattern 對象, def findall(pattern, string, flags=0): 進行非重疊匹配,返回模式中小括號 () 里的內容組成的列表,如果有多個小括號,則以元組 (tuple) 形式返回所有結果組成的列表;在結果列表中會包含空結果。下面是 標準模塊 re.py 中的源碼:

    def compile(pattern, flags=0):"Compile a regular expression pattern, returning a pattern object."return _compile(pattern, flags)def findall(pattern, string, flags=0):"""Return a list of all non-overlapping matches in the string.If one or more capturing groups are present in the pattern, returna list of groups; this will be a list of tuples if the patternhas more than one group.Empty matches are included in the result."""return _compile(pattern, flags).findall(string)
  • 筆者編寫這個正則表達式花了大約 1 個小時,中間遇到了很多坑,其中就包括了 3.2.2 節開頭提到的點 (主要問題還是筆者的 RegEx 水平爛),最后寫了個能用但很繁瑣的表達式 <div id\s*=\s*"buttons">\s*<ul>\s*.*?\s*<li.*?\s*<li><a[^>]+href\s*=\s*#\s*onclick\s*=\s*"location.href='(.*?)'">,正好由此簡單談一談我對正則表達式的看法:

    • 靈活性高,可以隨時調整;匹配速度比較快

    • 對使用者的要求高,容易寫錯,復雜匹配的正則表達式晦澀難懂

    • 十分脆弱,可能網頁標簽格式不對、或者網頁稍微變一下,整個正則表達式就失效了

    話雖如此,但還是有必要掌握基本的構造模式滴。

  • 筆者選擇了3個不同主題文獻的 DOI 組成了一個列表,從運行結果可見,飛行器那篇文獻匹配為空,筆者特意手動打開鏈接,發現不能正常訪問,這說明我們得到的 pdf 資源列表中可能存在不可用的項,需要篩選那些為空的項 (在后續方法中會考慮這點);另外,能訪問的鏈接也未必能正常下載,需要額外考慮這些情況

  • 輸出中有警告信息,暫且不要管

  • 2020-12-08 晴


    Beautiful Soup

    Beautiful Soup,不知道設計者為何取了個這個名字,但使用起來確實感覺 very beautiful 就是了。語法簡單,而且可以對 html 網頁的語法問題進行修復,唯一的瑕疵就是有些慢,不過能理解,畢竟是用純 Python 編寫的 (正則 和 Lxml 是 C 語言寫的)。

    需要安裝兩個模塊 (別忘了先進入虛擬環境) :

    conda install beautifulsoup4
    conda install html5lib

    直接上手,下面給出 用 BeautifulSoup 匹配超文本以獲取匹配內容列表 的 Python3 實現 (scraping_using_bs4.py):

    from bs4 import BeautifulSoup import redef get_link_using_bs4(html, parser='html5lib'):# parse the HTMLtry:soup = BeautifulSoup(html, parser)except:print('parser not available, now use the default parser "html.parser"...')parser = 'html.parser'soup = BeautifulSoup(html, parser)soup.prettify()div = soup.find('div', attrs={'id': 'buttons'})if div:a = div.find('a', attrs={'href': '#'})if a:a = a.attrs['onclick']return re.findall(r"location.href\s*=\s*'(.*?)'", a)[0]return Noneif __name__ == '__main__':from download import downloaddois = ['10.1016/j.apergo.2020.103286', # VR'10.1016/j.jallcom.2020.156728', # SOFC'10.3964/j.issn.1000-0593(2020)05-1356-06'] # 飛行器links = []for doi in dois:html = download(doi)# print(html)link = get_link_using_bs4(html)if link:links.append(link)for link in links:print(link)

    運行結果 (省去警告):

    Downloading: https://sci-hub.do/10.1016/j.apergo.2020.103286 Downloading: https://sci-hub.do/10.1016/j.jallcom.2020.156728 Downloading: https://sci-hub.do/10.3964/j.issn.1000-0593(2020)05-1356-06 //sci-hub.do/downloads/2020-12-01/29/joshi2021.pdf?download=true //sci-hub.do/downloads/2020-11-23/ac/tsvinkinberg2021.pdf?download=true

    對代碼的說明:

  • 上面的代碼采用了 BeautifulSoup + 正則表達式,主要做了如下幾件事:

    • soup.prettify() →\rightarrow 修復 html 文本存在的問題,規范格式

    • soup.find() →\rightarrow 根據所給標簽屬性定位元素位置,下面是定義 (element.py):

      def find(self, name=None, attrs={}, recursive=True, text=None,**kwargs):"""Return only the first child of this Tag matching the givencriteria."""r = Nonel = self.find_all(name, attrs, recursive, text, 1, **kwargs)if l:r = l[0]return r
  • re.findall(pattern, string) →\rightarrow 其中 string 是前面獲得的 onclick 屬性的內容,內容很規整,此時采用正則表達式處理更方便 (來自未來:其實是筆者不太熟悉 BeautifulSoup…)
  • 雖然沒有直接導入 html5lib,但不代表不需要 (除非你只需要用 html.parser)

  • 通過條件判斷是否為 None,初步篩選了用不了的鏈接

  • Lxml ?\star?

    和 BeautifulSoup 一樣,使用 Lxml 模塊的第一步也是將有可能不合法的 html 解析為統一格式;同樣地,Lxml 也可以正確解析屬性兩側缺失的引號,并閉合標簽,不過該模塊沒有額外添加 <html> 和 <body> 標簽,這些都不是標準 XML 的要求,因此對于 Lxml 來說,插入它們是不必要的。[1]

    本小節我們將使用選擇器來定位元素,包括 CSS選擇器XPath選擇器

    對于它們的相關說明,讀者可以通過以下參考鏈接查閱:

    • CSS選擇器
    • Xpath選擇器

    筆者這里列出幾個基本但常用的選擇器表達式,見下表:

    表 3.1 常用選擇器表達式的比較 [1] 選擇器描述XPath選擇器CSS選擇器
    選擇所有鏈接‘//a’‘a’
    選擇類名為"main"的 div 元素‘//div[@class=“main”]’‘div.main’
    選擇ID為"list"的 ul 元素‘//ul[@id=“list”]’‘ul#list’
    從所有段落中選擇文本‘//p/text()’None
    選擇所有類名中包含’test’的 div 元素‘//div[contains(@class, ‘test’)]’None
    選擇所有包含鏈接或列表的 div 元素‘//div[a|ul]’‘div a, div ul’
    選擇 href 屬性中包含 google.com 的鏈接‘//a[contains(@href, “google.com”)]’None

    在后續實踐中可能用到的CSS選擇器的補充:

    • 選擇任意標簽 →\rightarrow *
    • 選擇標簽 <a> 的孩子中標簽名為 <span> 的所有標簽 →\rightarrow a > span
    • 選擇標簽 <a> 的后代 (包括孩子) 中標簽名為 <span> 的所有標簽 →\rightarrow a span
    • 選擇標簽 <a> 中的屬性 title 值為 “Home” 的所有標簽 →\rightarrow a[title=Home]

    我們可以在開發者工具的控制臺 (Console) 中使用這些選擇器來預先調試我們的選擇器字符串,看看能否正常篩選。對于CSS選擇器,其在瀏覽器中的選擇器使用格式為 $('選擇器表達式');對于XPath選擇器,其在瀏覽器中的選擇器使用格式為 $x('選擇器表達式')

    在瀏覽器控制臺中使用選擇器

    下面先演示CSS選擇器在開發者工具中如何使用:

  • 隨意選一片文獻,比如筆者選擇了 https://sci-hub.do/10.1016/j.apergo.2020.103286

  • F12 打開開發者工具,切換到 Console 控制臺

  • 鍵入我們的CSS選擇表達式:$('div#buttons a') 或者 $('div#buttons > ul > li > a'),發現正確選擇了我們的目標標簽 <a>:

  • 對于XPath選擇器,我們甚至可以直接找到 onclick 屬性內容,只需輸入$x('//div[@id="buttons"]/ul/li/a')[0].attributes[1].textContent:

    在代碼中使用選擇器

    在瀏覽器中我們已經見識了選擇器的方便與強大,下面看看代碼中怎么使用它們。

    安裝 lxml 和 cssselect 模塊:conda install cssselect 、conda install lxml

    下面給出 用 lxml 以及一種選擇器匹配超文本以獲取匹配內容列表 的 Python3 實現 (scraping_using_lxml.py):

    from lxml.html import fromstringdef get_link_cssselect(html):try:tree = fromstring(html)a = tree.cssselect('div#buttons > ul > li > a')[0] # 區別onclick = a.get('onclick')return onclickexcept Exception as e:print('error occurred: ', e)return Nonedef get_link_xpath(html):try:tree = fromstring(html)a = tree.xpath('//div[@id="buttons"]/ul/li/a')[0] # 區別onclick = a.get('onclick')return onclickexcept Exception as e:print('error occurred: ', e)return Nonedef test_selector(selector):from download import downloaddois = ['10.1016/j.apergo.2020.103286', # VR'10.1016/j.jallcom.2020.156728', # SOFC'10.3964/j.issn.1000-0593(2020)05-1356-06'] # 飛行器links = []for doi in dois:html = download(doi)# print(html)link = selector(html)if link:links.append(link)for link in links:print(link)print('Done')if __name__ == '__main__':print('test_cssselect(): ')test_selector(get_link_cssselect)print('test_xpath(): ')test_selector(get_link_xpath)

    運行結果 (省去警告):

    test_cssselect(): Downloading: https://sci-hub.do/10.1016/j.apergo.2020.103286 Downloading: https://sci-hub.do/10.1016/j.jallcom.2020.156728 Downloading: https://sci-hub.do/10.3964/j.issn.1000-0593(2020)05-1356-06 error occurred: Document is empty location.href='//sci-hub.do/downloads/2020-12-01/29/joshi2021.pdf?download=true' location.href='//sci-hub.do/downloads/2020-11-23/ac/tsvinkinberg2021.pdf?download=true' Done test_xpath(): Downloading: https://sci-hub.do/10.1016/j.apergo.2020.103286 Downloading: https://sci-hub.do/10.1016/j.jallcom.2020.156728 Downloading: https://sci-hub.do/10.3964/j.issn.1000-0593(2020)05-1356-06 error occurred: list index out of range location.href='//sci-hub.do/downloads/2020-12-01/29/joshi2021.pdf?download=true' location.href='//sci-hub.do/downloads/2020-11-23/ac/tsvinkinberg2021.pdf?download=true' Done

    對代碼和結果的說明:

  • 兩種選擇器最終都達到了目標要求,而且兩種方法的代碼只有一行的差別,即 tree.cssselect() 以及 tree.xpath() 調用的那一行

  • lxml 模塊函數 fromstring(...) 用于統一 html 格式,并返回一個 document 或 element 對象

  • cssselect() 和 xpath() 均返回一個匹配列表,鑒于 sci-hub 目標元素所在層級中只存在一個匹配,所以我們取列表中的 0 位置元素

  • get(attr) 方法用于獲取特定標簽屬性的內容,實踐中我們要找的是 <a> 標簽的 onclick 屬性

  • 注意異常的處理 (第3個 doi 獲取的網頁是不合法的)

  • 這里還沒有篩選完,我們可以沿用 BeautifulSoup 小節的方式,采用正則表達式作為最后的篩選工作:return re.findall(r"location.href\s*=\s*'(.*?)'", onclick)[0],讀者可以自行補上 (需要導入 re 模塊)

  • 2020-12-09 晴


    3.2.3 根據獲得的 pdf 鏈接執行下載

    下載鏈接得到了,我們通過組裝鏈接構成絕對 url,然后使用 request 模塊的 get() 方法請求資源,最后將獲得的內容以二進制流的操作寫入文件即可。

    下面給出 給定 DOI 執行一次相應文獻的 pdf 下載 的 Python3 實現 (download.py):

    import requestsdef download_pdf(url, user_agent="sheng", proxies=None, num_retries=2):headers = {'User-Agent': user_agent}url = 'https:{}'.format(url) # 改動1print('Downloading: ', url)try:resp = requests.get(url, headers=headers, proxies=proxies, verify=False)if resp.status_code >= 400:print('Download error: ', resp.status_code)if num_retries and 500 <= resp.status_code < 600:return download(url, user_agent, proxies, num_retries-1)# ok, let's write it to filewith open('file.pdf', 'wb') as fp: # 改動2,注意 'wb' 而不是 'w'fp.write(resp.content)except requests.exceptions.RequestException as e:print('Download error', e) # 簡單的測試 if __name__ == '__main__':doi = '10.1016/j.apergo.2020.103286'html = download(doi) # 獲取文獻資源網頁的 html 文本from scraping_using_lxml import get_link_xpathurl = get_link_xpath(html) # 提取下載鏈接download_pdf(url) # 執行下載print('Done.')

    運行結果:


    對代碼的說明:

  • 注意 url 的拼接格式

  • 注意是用 'wb',即二進制流寫入的方式打開的文件

  • 測試代碼中使用的是 XPath 選擇器提取下載鏈接,這里換成 3.2.2 節中任意一種方式都可行 (可能有一些細節需要變化)

  • 這里的文件名暫時用一個比較固定的 file.pdf,如果執行批量下載,我們肯定得找一個能概括此文獻的文本作為其名稱,以方便我們后續查閱,容易想到文獻標題是一個不錯的名稱候選,因此我們在下載之前,還需要抓取文獻的標題 (或其他能唯一標識文獻的文本),3.2.4 節會介紹改進方法

  • 3.2.4 看看哪些地方仍需改進

    磁盤文件合法命名

    對于文件名稱,我們有以下要求:

    • 不重復 (在目錄中唯一地標識一個文件)

    • 有意義 (便于查找)

    綜上,我們選擇文獻標題作為文件名 (不要抬杠)。那么問題來了,能不能不做任何轉換就拿來用?比如其中一篇文獻的題名為:

    Implementing Virtual Reality technology for safety training in the precast/ prestressed concrete industry. Applied Ergonomics, 90, 103286.

    我們注意到,此標題中含有 /,而文件名稱不能含有 \ / ? * < > | : " (共9個字符),所以不能直接拿來作為文件名稱。我們需要作一些轉換使得以標題作為文件名合法,且限制長度在操作系統要求的最大值之內 (WIn10 是 260字節,但經筆者測試實際最大命名長度低于此值。保險起見,我們默認設置長度為 128 字節)。代碼非常簡單:

    import redef get_valid_filename(filename, name_len=128):# return re.sub(r'[/\\|*<>?":]', '_', filename)[:name_len] # '\n' 來自未來:這些轉義符號會算作合法,但會出錯return re.sub(r'[^0-9A-Za-z\-,._;]', '_', filename)[:name_len] # 這個可以if __name__ == '__main__':title = r'''Implementing Virtual Reality technology for safety training in the precast/ prestressed concrete industry. Applied Ergonomics, 90, 103286.'''print(get_valid_filename(title))print(get_valid_filename(title, 40))

    運行結果:

    Implementing Virtual Reality technology for safety training in the precast_ prestressed concrete industry. Applied Ergonomics, 90, 103286. Implementing Virtual Reality technology

    從結果可見,/ 被替換成了下劃線 _,其余合法字符沒變;另外,第二行輸出被限制了長度。

    2020-12-10 晴


    獲得文件所需的名稱 —— 文獻標題

    現在瀏覽器中用"選擇元素" (Ctrl + Shift + C) 對標題定位一波,然后使用XPath選擇器篩選出標題文本 (CSS選擇器類似):$x('//div[@id="citation"]/i/text()')[0],然后筆者寫好代碼套用該選擇器時,發現某些文獻標題并沒有 <i> 標簽,所以需要加判斷 (比如零長度等等)

    修改我們在 3.2.2 節寫的 scraping_using_lxml.py,之前我們只返回了一個 onclick 中的下載鏈接,我們現在要額外返回一個標題名稱,使用字典是一個不錯的選擇:

    from lxml.html import fromstring import redef get_link_cssselect(html):try:tree = fromstring(html)a = tree.cssselect('div#buttons > ul > li > a')[0]onclick = a.get('onclick')title = tree.cssselect('div#menu > div#citation > i') # 1if len(title) == 0: # 2title = tree.cssselect('div#menu > div#citation')title = title[0].text # 3onclick = re.findall(r"location.href\s*=\s*'(.*?)'", onclick)[0]return {'title': title, 'onclick': onclick} # 4except Exception as e:print('error occurred: ', e)return Nonedef get_link_xpath(html):try:tree = fromstring(html)a = tree.xpath('//div[@id="butdtons"]/ul/li/a')[0]onclick = a.get('onclick')onclick = re.findall(r"location.href\s*=\s*'(.*?)'", onclick)[0]title = tree.xpath('//div[@id="citation"]/i/text()') # 1if len(title) == 0: # 2title = tree.xpath('//div[@id="citation"]/text()')return {'title': title[0], 'onclick': onclick} # 3except Exception as e:print('error occurred: ', e)return None

    對代碼的說明:

  • 筆者后續實踐中發現,不是所有文獻標題都有 <i> 標簽,因此需要加個判斷,即當匹配列表為空時,匹配其父級內容作為標題

  • 注意改動的部分 (后面加注了數字)

  • 正則表達式和 Beautiful Soup也采用相似的修改方式,只需要多抓取一個標題名稱就行,筆者在此僅給出主要修改處的代碼,其余保持不變:

    # Beautiful Soup (scraping_using_bs4.py) def get_link_using_bs4(html, parser='html5lib'):try:...except:...# 修改的部分try:div = soup.find('div', attrs={'id': 'buttons'})if div:a = div.find('a', attrs={'href': '#'})if a:a = a.attrs['onclick']onclick = re.findall(r"location.href\s*=\s*'(.*?)'", a)[0]div = soup.find('div', attrs={'id': 'citation'})title = div.find('i')if title:title = title.get_text()else:title = div.get_text()return {'title': title, 'onclick': onclick}except Exception as e:print('error occured: ', e)return None # --------------------------------------------------------------------------- # regular expression (scraping_using_regex.py) def get_links(pattern, html):...def get_link_using_regex(html):pattern_onclick = '''<div id\s*=\s*"buttons">\s*<ul>\s*.*?\s*<li.*?\s*<li><a[^>]+href\s*=\s*#\s*onclick\s*=\s*"location.href='(.*?)'">'''pattern_title = '''<div id\s*=\s*"citation"[^>]+>(.*?)</div>'''try:title = get_links(pattern_title, html)[0]if title:i = get_links('<i>(.*?)</i>', title)title = i[0] if i else titleonclick = get_links(pattern_onclick, html)[0]if onclick and title:return {'title': title, 'onclick': onclick}elif onclick:print('No title, now use onclick string to be the title.')return {'title': onclick, 'onclick': onclick}except Exception as e:print('error occurred: ', e)return Noneif __name__ == '__main__':from download import downloadfrom download import doi_parserdois = ['10.1016/j.apergo.2020.103286', # VR'10.1016/j.jallcom.2020.156728', # SOFC'10.3964/j.issn.1000-0593(2020)05-1356-06'] # 飛行器links = []for doi in dois:url = doi_parser(doi, 'sci-hub.do')html = download(url, headers={'User-Agent': 'sheng'})link = get_link_using_regex(html)if link:links.append(link)for link in links:print(link)
    robots.txt 解析以及下載時間間隔設置

    還記得 2.3.2 節提到的 robots.txt 嗎?它是我們進行爬蟲前的一個參考,為了降低爬蟲被封禁的風險,我們需要遵守其中的約束,可以在 網站域名 + /robots.txt 查看文件要求,我們在 2.3.2 節已經初步分析過了,只要我們的用戶代理不是 Twitterbot 并且不以它為子串,那么就沒有限制。盡管如此,我們還是可以設置一個下載的間隔時間,并且在發送請求前檢查請求是否符合 robots.txt 的規定,這樣我們的爬蟲便可以適應更多的變化。

    我們可以在請求文獻內容前進行進行一次 robots.txt 驗證,如果驗證通過我們再執行下載,并設置下載時間間隔。我們正好借此機會調整一下之前的代碼設計,盡可能減少功能之間的耦合 (download.py):

    import requests from urllib.robotparser import RobotFileParser import time from urllib.parse import urlparse from filename import get_valid_filenamedef doi_parser(doi, start_url, useSSL=True):"""Parse doi to url"""HTTP = 'https' if useSSL else 'http'url = HTTP + '://{}/{}'.format(start_url, doi)return urldef get_robot_parser(robot_url):"""解析robots.txt"""rp = RobotFileParser()rp.set_url(robot_url)rp.read()return rp"""延時函數""" def wait(url, delay=3, domains={}):"""wait until the interval between twodownloads of the same domain reaches time delay"""domain = urlparse(url).netloc # get the domainlast_accessed = domains.get(domain) # the time last accessedif delay > 0 and last_accessed is not None:sleep_secs = delay - (time.time() - last_accessed)if sleep_secs > 0:time.sleep(sleep_secs)domains[domain] = time.time()def download(url, headers, proxies=None, num_retries=2):print('Downloading: ', url)try:resp = requests.get(url, headers=headers, proxies=proxies, verify=False)html = resp.textif resp.status_code >= 400:print('Download error: ', resp.text)html = Noneif num_retries and 500 <= resp.status_code < 600:return download(url, headers, proxies, num_retries-1)except requests.exceptions.RequestException as e:print('Download error', e)return Nonereturn htmldef download_pdf(result, headers, proxies=None, num_retries=2):url = result['onclick']url = 'https:{}'.format(url)print('Downloading: ', url)try:resp = requests.get(url, headers=headers, proxies=proxies, verify=False)if resp.status_code >= 400:print('Download error: ', resp.status_code)if num_retries and 500 <= resp.status_code < 600:return download(result, headers, proxies, num_retries-1)filename = get_valid_filename(result['title']) + '.pdf'print(filename)# ok, let's write it to filewith open(filename, 'wb') as fp:fp.write(resp.content)except requests.exceptions.RequestException as e:print('Download error', e)return Falsereturn Truedef sci_hub_crawler(doi_list, robot_url=None, user_agent='sheng', proxies=None,num_retries=2, delay=3, start_url='sci-hub.do', useSSL=True, get_link=None, nolimit=False):"""給定文獻doi列表,爬取對應文獻的 pdf 文件:param doi_list: doi列表:param robot_url: robots.txt在sci-bub上的url:param user_agent: 用戶代理,不要設為 'Twitterbot':param proxies: 代理:param num_retries: 下載重試次數:param delay: 下載間隔時間:param start_url: sci-hub 主頁域名:param useSSL: 是否開啟 SSL,開啟后HTTP協議名稱為 'https':param get_link: 抓取下載鏈接的函數對象,調用方式 get_link(html) -> html -- 請求的網頁文本所使用的函數在 scraping_using_%s.py % (bs4, lxml, regex) 內:param nolimit: 是否遵循 robots.txt 的約束,如果為True則不受其限制:return:"""headers = {'User-Agent': user_agent}HTTP = 'https' if useSSL else 'http'if not get_link:print('Crawl failed, no get_link method.')return Noneif not robot_url:robot_url = HTTP + '://{}/robots.txt'.format(start_url)try:rp = get_robot_parser(robot_url)except Exception as e:rp = Noneprint('get_robot_parser() error: ', e)domains={} # save the timestamp of accessed domainsdownload_succ_cnt: int = 0 # the number of pdfs that're successfully downloadedfor doi in doi_list:url = doi_parser(doi, start_url, useSSL)if rp and rp.can_fetch(user_agent, url) or nolimit:wait(url, delay, domains)html = download(url, headers, proxies, num_retries)result = get_link(html)if result and download_pdf(result, headers, proxies, num_retries):download_succ_cnt += 1else:print('Blocked by robots.txt: ', url)print('%d of total %d pdf success' % (download_succ_cnt, len(doi_list)))if __name__ == '__main__':from scraping_using_lxml import get_link_xpath, get_link_cssselectfrom scraping_using_bs4 import get_link_using_bs4from scraping_using_regex import get_link_using_regexfrom random import choicedois = ['10.1016/j.apergo.2020.103286', # VR'10.1016/j.jallcom.2020.156728', # SOFC'10.3964/j.issn.1000-0593(2020)05-1356-06'] # 飛行器get_links_methods = [get_link_xpath, get_link_cssselect, get_link_using_bs4, get_link_using_regex]get_link = choice(get_links_methods)print('use %s as get_link_method.' % get_link.__name__)print('obey the limits in robots.txt: ')sci_hub_crawler(dois, get_link=get_link, user_agent='sheng')print('no any limit: ')sci_hub_crawler(dois, get_link=get_link, user_agent='sheng', nolimit=True)print('Done.')

    運行結果:

    use get_link_xpath as get_link_method. obey the limits in robots.txt: Blocked by robots.txt: https://sci-hub.do/10.1016/j.apergo.2020.103286 Blocked by robots.txt: https://sci-hub.do/10.1016/j.jallcom.2020.156728 Blocked by robots.txt: https://sci-hub.do/10.3964/j.issn.1000-0593(2020)05-1356-06 0 of total 3 pdf success no any limit: Downloading: https://sci-hub.do/10.1016/j.apergo.2020.103286 Downloading: https://sci-hub.do/downloads/2020-12-01/29/joshi2021.pdf?download=true Implementing Virtual Reality technology for safety training in the precast_ prestressed concrete industry. Applied Ergonomics, 9.pdf Downloading: https://sci-hub.do/10.1016/j.jallcom.2020.156728 Downloading: https://sci-hub.do/downloads/2020-11-23/ac/tsvinkinberg2021.pdf?download=true Tsvinkinberg, V. A., Tolkacheva, A. S., Filonova, E. A., Gyrdasova, O. I., Pikalov, S. M., Vorotnikov, V. A., … Pikalova, E. Y. .pdf Downloading: https://sci-hub.do/10.3964/j.issn.1000-0593(2020)05-1356-06 error occurred: Document is empty 2 of total 3 pdf success Done.

    對代碼和結果的說明:

  • 代碼可能有點長,但是其中很多函數在之前已經出現過了,大部分函數只作了很小部分的改動:比如,download() 和 download_pdf() 不再傳入 doi,而是傳入對應的 url。另外,新增了 doi_parser() 轉換函數,這樣就實現了解耦,能讓 download() 具有通用性;新增的 get_robot_parser() 以及 can_fetch() 函數實現了 robots.txt 的解析,并遵循其中的約束; wait() 函數設置了下載間隔時間

  • sci_hub_crawler() 集成了"根據給定的 DOI 列表批量(串行)爬取對應的 pdf 文件"的功能,其參數列表的說明在函數開頭標注了。如此一來,當我們爬取到 doi 列表后,只需要調用 sci_hub_crawler() 并睡上一覺就行了

  • 主函數中我們使用了一個 get_links_methods 列表存儲了所有抓取方法,然后使用 random.choice() (偽)隨機選取了其中一個,傳給了 sci_hub_crawler() 的 get_link 參數,這其實就是多態性的一種體現 —— 同一種調用(get_link(html)),不一樣的方法。這類似于 C# 中的委托 (delegate) 或是 C/C++ 的函數指針。但要求 get_link_methods 中的所有函數參數列表一致,從實用性來看,要保證非默認參數的個數和順序相同。

  • 從運行結果來看,似乎 robots.txt 中的約束比我們之前解讀的要強很多 —— 它不允許我們爬取資源,但我們仍然可以 “知不可為而為之” (設置 nolimit=True)。只不過為了降低可能的封禁隱患,我們可以讓下載間隔大一些(比如 5 - 10s,這樣按照兩分鐘一個的速率一夜也能爬個200+文件,這夠多了)。不過也別高估了這個 sci_hub_crawler(),它就是個串行爬蟲,想讓服務器崩潰可沒那么容易,所以我們還是可以放心爬 (大不了就是幾天的封禁嘛)

  • 添加一個簡單的緩存類 Cache

    有時候我們可能因為不可抗力 (比如斷網、死機等) 而不得不中止我們的爬取,設想這樣一個情況:我們要爬取1000個文件,然而我們在下載到第501個文件時出現了上述的意外,當一切恢復正常后,我們想要繼續從第 501 個文件處開始下載,怎么辦? 一種極簡的方法是:設立一個變量以記錄我們當前已經成功下載的文件個數,并且每當一個文件下載成功時,將此變量寫入一個文件 (比如 .txt),重啟下載時讀取該變量值,從它的下一個序號開始下載即可。

    以上方法適用于我們的 DOI 列表項順序不變的情況,事實上對于我們這個小項目來說已經滿足要求了;但還有一種普適性更強的方法,那就是按鍵值對存儲已經下載的資源標識,這里我們可以選用 {文獻url: pdf_url} 作為資源標識,借用 Python3 標準庫中的 json 模塊來實現緩存數據加載和存儲。

    由于我們的緩存在內存中以字典形式存儲,與此同時需要訪問外存,進行緩存讀寫,我們可以將緩存功能封裝在一個類中,并通過特殊成員函數 __getitem__() 和 __setitem__() 使得類對象的操作行為類似于字典對象。

    下面構建一個 Cache 類 (cache.py):

    import json import osclass Cache:def __init__(self, cache_dir):self.cache_dir = cache_dir # 緩存文件的路徑self.cache = self.read_cache() # 加載緩存數據,是個字典def __getitem__(self, url): # 例如,對于類對象cache,執行 cache[url] 將調用此方法if self.cache.get(url):return self.cache[url]else:return Nonedef __setitem__(self, key, value): # key -> url value -> pdf_url 執行 cache[url] = pdf_url 將調用此方法"""將{url: pdf_url} 追加到字典中,并寫入外存"""filename = self.cache_dirself.cache[key] = valueif os.path.exists(filename):with open(filename, 'r') as fp:if os.path.getsize(filename):cache = json.load(fp)else:cache = {}cache.update({key: value})with open(filename, 'w') as fp:json.dump(cache, fp, indent=0) # 加換行符def read_cache(self):"""加載json數據成為Python字典對象,至少也是個空字典"""try:filename = self.cache_dirif os.path.exists(filename):if os.path.getsize(filename):with open(filename, 'r', encoding='utf-8') as fp:return json.load(fp)else:return {}else:with open(filename, 'w', encoding='utf-8'):return {}except Exception as e:print('read_cache() error: ', e)return {}

    要使用此類,我們得修改 sci_hub_crawler(),下面僅展示更改的代碼 (download.py):

    def sci_hub_crawler(doi_list, robot_url=None, user_agent='sheng', proxies=None,num_retries=2,delay=3, start_url='sci-hub.do', useSSL=True, get_link=None, nolimit=False, cache=None):"""...:param cache: 應傳入一個緩存類對象,在此代碼塊中我們應把它當作字典使用..."""...try:...for doi in doi_list:...if cache and cache[url]: # 如果緩存中存在對應 url,那么跳過后續下載步驟print('already downloaded: ', cache[url])download_succ_cnt += 1continueif rp and rp.can_fetch(user_agent, url) or nolimit:...if result and download_pdf(result, headers, proxies, num_retries):if cache:cache[url] = 'https:{}'.format(result['onclick']) # cache...

    正如函數開頭注釋所說,雖然cache是個Cache類的對象,但是由于類中的特殊函數(上文已經提及),實現了運算符重載,我們可以像使用字典一樣使用它。

    下面我們可以簡單測試一下新增的緩存功能 (cache.py):

    if __name__ == '__main__':from download import sci_hub_crawlerfrom scraping_using_lxml import get_link_xpathcache_dir = './cache.txt'dois = ['10.1016/j.apergo.2020.103286', # VR'10.1016/j.jallcom.2020.156728', # SOFC'10.3964/j.issn.1000-0593(2020)05-1356-06'] # 飛行器sci_hub_crawler(dois, get_link=get_link_xpath, user_agent='sheng', nolimit=True, cache=Cache(cache_dir))print('Done.')

    運行結果與說明:

  • 初次運行,文件下載符合預期,并且在代碼的同級目錄下生成了 cache.txt 文件,內容如下:

    { "https://sci-hub.do/10.1016/j.apergo.2020.103286": "https://sci-hub.do/downloads/2020-12-01/29/joshi2021.pdf?download=true", "https://sci-hub.do/10.1016/j.jallcom.2020.156728": "https://sci-hub.do/downloads/2020-11-23/ac/tsvinkinberg2021.pdf?download=true" }

    上述內容加載到內存后是一個 Python 字典,鍵是 sci-hub 上輸入 doi 后搜索所得頁面的 url,值是相應 pdf 資源的 url

  • 第二次運行,由于文獻已經下載過了,除了第三個異常的鏈接外,其余文獻將不再執行下載,而是給出"已經下載"的提示:

    already downloaded: https://sci-hub.do/downloads/2020-12-01/29/joshi2021.pdf?download=true already downloaded: https://sci-hub.do/downloads/2020-11-23/ac/tsvinkinberg2021.pdf?download=true Downloading: https://sci-hub.do/10.3964/j.issn.1000-0593(2020)05-1356-06 error occurred: Document is empty 2 of total 3 pdf success Done.
  • 雖然還存在很多可以改進的地方,但現在是時候打住了,現在的版本已經符合要求了 (再優化就寫不完了)。

    3.3 回到 Web of Science,提取搜索頁的 DOI 列表

    至此,我們已經翻過了最高的山,剩余工作很簡單 —— 抓取 DOI 就完事了,它與 3.2 節的不同之處:

    • 網站不同,意味著元素選擇會有所改變

    • 只有文本抓取,沒有二進制數據流的下載過程

    是不是非常簡單?我們要做的是抓取 html 文本中的 DOI,然后用列表存起來,還可以把它寫入磁盤。這些操作我們在 3.2 節已經見過了。但是 —— 你怎么獲得搜索結果中所有的文獻鏈接呢 (搜索結果往往分布在多個分頁里) ?其實我們在 2.1 節已經討論過了這個問題,并且給出了解決方案,筆者在此畫個示意圖,展現一下 Web of Science 搜索結果的層級結構:

    該示意圖其實展示了一個比較通用的爬蟲模型 —— 鏈接爬蟲 (Link Crawler),它可以通過一個源鏈接,跟蹤頁面中的其他鏈接,使得爬蟲表現得更像普通用戶 [1],降低封禁風險。(一頁頁地瀏覽,并且按順序訪問文獻,的確符合 “普通用戶” 的行為)

    筆者這里不再對鏈接爬蟲作過多展開,原因有二:其一,筆者爬取 Web of Science 的過程中沒被封禁過,而且也沒找到該網站的 robots.txt,再加上這是串行爬取,訪問時也就省去了普通用戶的控件操作時間,對網站服務器的負載貢獻不大;其二,這種方法相對較慢,為了獲取 doi,它還需要額外花時間爬取鏈接。

    事實上,針對這個網站有更高效的方法

    2020-12-11 晴


    3.3.1 方法一:修改 doc 屬性值快速構建 url,然后從中爬取 doi

    這是筆者點進一篇文獻的網站,觀察 url 鏈接發現的一種方法,此方法不需要用到分頁,可以直接獲取每個文獻鏈接。我們看一下第 1 頁第 1 篇文獻的 url:

    http://apps.webofknowledge.com/full_record.do?product=UA&search_mode= GeneralSearch&qid=30&SID=8FZeNUIigweW9fYyFJn&page=1&doc=1

    試著解析一下這個 url:

  • http://apps.webofknowledge.com/ →\rightarrow Web of Science 主頁鏈接

  • xxx.do →\rightarrow 是個網頁后臺程序,剛點搜索彈出的頁面便是 Search.do、切換分頁時為 Summary.do,打開具體某一文獻時為 full_record.do

  • ?attr1=value1&attr2=value2&... →\rightarrow 問號后面接一個或多個用 & 分隔開來的變量,并設定一定值,從而實現動態鏈接,也就是說對于不同的屬性以及屬性值,會生成不同的網頁。那我們來看看上面那個鏈接跟了些啥參數吧:

  • product。這個不用管,所有頁面都一樣

  • search_mode。 看名字就是知道,指搜索模式,這個也不用管

  • qid、SID。不知道啥意思,但不可少,而且同一個搜索結果下所有文獻網站的 qid 和 SID 都一樣,所以我們保持原樣即可

  • page。分頁號碼,對應的便是不同分頁,可能有用。(但事實上這種分頁與結果列表本身沒有關系,只是刻意限定了每頁的結果數目而已,所以很可能也不用管)

  • doc。文獻搜索序號,與分頁號無關,當 page 和 doc 共存時 doc “說得算”,你會發現即使沒有分頁號也能正常打開目標網頁,說明分頁號page不重要,重要的是文獻搜索序列號doc!!!

  • 如此一來,我們得到了如下三個子問題,并且都很好解決:

  • url 轉換,給定一個搜索結果源鏈接 (必須是文獻鏈接而不是搜索頁或分頁鏈接),其格式為 http://apps.webofknowledge.com/full_record.do?attr1=value1&attr2=...&attrn=valuen&doc=num, 要獲取搜索列表中第 iii 篇文獻網頁,將 url 末尾參數 doc 改變,使得 &doc=i 即可,此時鏈接變為:http://apps.webofknowledge.com/full_record.do?attr1=value1&attr2=...&attrn=valuen&doc=i

  • 抓取搜索結果總數:<span id=“hitCount.top”>21,322</span>,注意搜索結果總數中的逗號,要把它轉變為整數。不過,筆者偷下懶,把這項任務交給用戶,人眼"識別"結果總數,并傳到接口的相應參數中。

  • 抓取文獻網頁中的 DOI:標簽特征在 2.2 節已經解析過,只需采用 3.2.2 節的一種抓取方法即可 (筆者使用XPath選擇器:'//span[text()="DOI:"]/following::*[1]')[0].text())

    <p class="FR_field"> <span class="FR_label">DOI:</span> <value>10.1016/j.electacta.2020.137142</value> </p>
  • 下面是筆者 抓取一定數目搜索結果的 DOI 并構成列表 的 Python3 實現 (doi_crawler.py):

    from download import download import re from lxml.html import fromstringdef url_changer(source_url):"""獲取文獻網站url的模式"""url = re.findall(r'''(.*)&doc''', source_url)[0]doc = '&doc='return url + docdef get_doi(html):"""根據獲取到的html獲得其中的doi并返回"""try:tree = fromstring(html)doi = tree.xpath('//span[text()="DOI:"]/following::*[1]')[0].textreturn doiexcept Exception as e:print('get_doi() error: ', e)return Nonedef doi_crawler(pattern_url, headers=None, number=500):""" 獲得搜索結果中第 [1, number] 的 doipass the following parameter:param pattern_url: 搜索結果內任意一篇文獻的url,不是分頁或者搜索結果頁的!:param number: doi獲取數目,不要超過頁面最大結果數"""if headers is None:headers = {'User-Agent': 'sheng'}base_url = url_changer(pattern_url)dois = []for i in range(1, number + 1):url = base_url + str(i)html = download(url, headers)doi = get_doi(html)if doi:dois.append(doi)return doisdef save_doi_list(dois, filename):"""將doi列表項以[filename].txt保存到當前文件夾中,"""filepath = filename[:128] + '.txt'try:with open(filepath, 'w') as fp:for doi in dois:fp.writelines(doi + '\n')except Exception as e:print('save error: ', e)def read_dois_from_disk(filename):"""從磁盤文件[filename].txt中按行讀取doi,返回一個doi列表"""dois = []try:filepath = filename + '.txt'with open(filepath, 'r') as fp:lines = fp.readlines()for line in lines:dois.append(line.strip('\n'))return doisexcept Exception as e:print('read error: ', e)return Noneif __name__ == '__main__':import timesource_url = 'http://apps.webofknowledge.com/full_record.do?product=UA&' \'search_mode=GeneralSearch&qid=2&SID=6F9FiowVadibIcYJShe&page=1&doc=2'start = time.time()dois = doi_crawler(source_url, number=10)save_doi_list(dois, 'dois')print('time spent: %ds' % (time.time()-start))print('now read the dois from disk: ')doi_list = read_dois_from_disk('dois')for doi in doi_list:print(doi)

    運行結果:

    Downloading: http://apps.webofknowledge.com/full_record.do?...&doc=1 ... Downloading: http://apps.webofknowledge.com/full_record.do?...&doc=10 time spent: 9s now read the dois from disk: 10.1016/j.apcatb.2020.119553 ... 10.1016/j.ceramint.2020.08.241

    對代碼與結果的說明:

  • 雖然有很多函數,但函數結構非常簡單,而且對函數參數和功能作了注釋,就不過多解讀了。讀者可以從主函數片段中得知主要的函數接口 (有 3 個,分別是 doi_crawler() 、save_doi_list() 、 read_dois_from_disk() )

  • XPath選擇器的構造參考了一位博主的博客 [2],鏈接:XPath 選取具有特定文本值的節點

  • 筆者僅選取了搜索結果前 10 項,測試了多次,耗時在 9 - 15s 范圍內,也就是大約 1 秒 1 個 doi,不知道讀者能否接受這個速度呢 (反正筆者感覺還可以)

  • 爬蟲受網絡因素影響,偶爾會爬取失敗,重試幾次就好了 (sci_hub_crawler() 也一樣)

  • 與 3.2 節的 sci_hub_crawler() 不同,本節給用戶留了兩個小任務:① 提供一個文獻的鏈接;② 設定最大 doi 個數

  • 3.3.2 方法二:結合 Web of Science 導出功能的"零封禁幾率"方法

    上面的方法雖然通過找規律的方式省去了爬取文獻鏈接的過程,提高了效率,但并不能保證在進行大量爬取時會免受封禁。好在 Web of Science 網站提供了一個便利的功能 —— 導出選擇的選項。它通過一個按鈕控件的點擊事件觸發,如下圖所示:

    ????? ???????????? ???????

    筆者以 Unity3D 為主題,試著導出第 1 至 500 項,以 html 的格式保存文獻數據。然后我們打開此文件 (savedrecs.html,即 save document records),找尋 DOI 所在位置, 如下所示:

    根據筆者觀察,幾乎每一個 <td> 標簽的屬性 valign 值是一致的,那么我們就只能根據文本 “DI” 來定位并選擇其下一個兄弟元素的方式來獲取目標 DOI 了。因此,筆者采用 XPath 選擇器,使用的選擇字符串與 3.3.1 節類似。

    下面給出 根據導出的 html 記錄,抓取其中的 DOI 并返回列表 的 Python3 實現 (advanced_doi_crawler.py):

    from lxml.html import fromstringdef get_doi(html):"""根據獲取到的html獲得其中的doi并返回"""results = []try:tree = fromstring(html)dois = tree.xpath('//td[text()="DI "]/following::*[1]')for doi in dois:results.append(doi.text)return resultsexcept Exception as e:print('get_doi() error: ', e)return Nonedef doi_crawler(filepath):"""html 導出文件的路徑"""try:with open(filepath, 'r', encoding='utf-8') as fp:html = fp.read()doi_list = get_doi(html)return doi_listexcept Exception as e:print('doi_crawler() error', e)return Noneif __name__ == '__main__':import timestart = time.time()filepath = './data.html'doi_list = doi_crawler(filepath)print('time spent: %ds' % (time.time() - start))print('%d doi records in total: ' % len(doi_list))for doi in doi_list:print(doi)print('Done.')

    運行結果:

    time spent: 0s 206 doi records in total: 10.1016/j.apergo.2020.103286 #1 10.11607/ijp.6835 #2 ... 10.1016/j.proeng.2017.10.509 #206 Done.

    對代碼與結果的說明:

  • xpath() 返回的是一個列表,只不過之前的實踐我們經常只要其中第一項,這里存在多個匹配,所以我們全都要

  • doi_crawler() 中的文件讀取用的是 read(),而不是用 readlines()。前者一次讀取完;后者讀取所有行,保存在一個列表中 [3]

  • 從結果看,500 條記錄中僅僅爬取了 206 個 DOI,這是正常的 —— Unity3D 的很多成果都是以會議形式發表的;

  • 與 3.3.1 的方法相比,兩種方法的時間開銷完全不是一個級別的 —— 此方法 1s 之內即可完成;如果換作之前的方法,耗時將近 10 min

  • STEP4 組裝起來,形成終極接口:sci_spider()

    我們分別用 3.2 節 和 3.3 節 制作了 sci_hub_crawler() 和 doi_crawler() (筆者用 3.3.2 節的),并作了簡單的測試,至少現在沒看到問題。那么把它們組合起來會不會引入新問題呢?實踐一下就知道了!

    筆者先在此列出待調用函數的函數原型,作為流程梳理的參考:

    def doi_crawler(filepath): pass # in advanced_doi_crawler.pydef sci_hub_crawler(doi_list, robot_url=None, user_agent='sheng', proxies=None,num_retries=2,delay=3, start_url='sci-hub.do', useSSL=True, get_link=None, nolimit=False, cache=None):pass # in download.pydef get_link_xpath(html):pass # in scraping_using_lxml.py

    注:盡管筆者可能在某一步驟使用了多種方法來實現,但此處筆者只選擇一種方案,其余方案就不再展示實現方法了,但思路都是一致的。具體來說,筆者抓取標簽內容使用的是 XPath 選擇器;"獲取 DOI 列表"采用的是 3.3.2 節的方法。

    4.1 流程梳理 ?\star?

    本節實際上是本爬蟲的使用說明書

  • 打開 Web of Science,搜索感興趣的內容,得到一個搜索結果列表

  • 點擊 “導出為其他文件格式” 按鈕,記錄條數自選,記錄內容作者、標題、來源出版物文件格式選擇HTML,然后點擊"導出",記錄該 html 文件的 絕對路徑 filepath (也可以是相對路徑)

  • 調用 doi_crawler(filepath),返回一個 doi 列表,將之命名為 doi_list

  • 調用 sci_hub_crawler(doi_list, get_link=get_link_xpath, nolimit=True, cache=Cache(cache_dir)),如果不需要緩存,可以不傳參至 cache。另外說明的是,cache_dir 是緩存文件的路徑,一般用相對路徑即可;其余參數根據需要來調整

  • 睡上一覺,等待結果

  • 4.2 組裝起來,給它取個名字,就叫 “sci_spider” 好了

    上面流程已經說的很清楚了,組裝起來不是什么難事,但需要注意:組裝的這些函數的參數列表需要合理地合并。

    下面就是筆者組裝的情況 (sci_spider.py):

    from download import sci_hub_crawler from scraping_using_lxml import get_link_xpath from cache import Cache from advanced_doi_crawler import doi_crawlerdef sci_spider(savedrec_html_filepath, robot_url=None, user_agent='sheng', proxies=None, num_retries=2,delay=3, start_url='sci-hub.do', useSSL=True, get_link=get_link_xpath,nolimit=False, cache=None):"""給定一個文獻索引導出文件 (來自 Web of Science),(按照DOI)下載文獻對應的 pdf文件 (來自 sci-hub):param savedrec_html_filepath: 搜索結果的導出文件 (.html),其中含有文獻記錄 (每一條記錄可能有doi,也可能沒有):param robot_url: robots.txt在sci-bub上的url:param user_agent: 用戶代理,不要設為 'Twitterbot':param proxies: 代理:param num_retries: 下載重試次數:param delay: 下載間隔時間:param start_url: sci-hub 主頁域名:param useSSL: 是否開啟 SSL,開啟后HTTP協議名稱為 'https':param get_link: 抓取下載鏈接的函數對象,調用方式 get_link(html) -> html -- 請求的網頁文本所使用的函數在 scraping_using_%s.py % (bs4, lxml, regex) 內,默認用xpath選擇器:param nolimit: do not be limited by robots.txt if True:param cache: 一個緩存類對象,在此代碼塊中我們完全把它當作字典使用"""print('trying to collect the doi list...')doi_list = doi_crawler(savedrec_html_filepath) # 得到 doi 列表if not doi_list:print('doi list is empty, crawl aborted...')else:print('doi_crawler process succeed.')print('now trying to download the pdf files from sci-hub...')sci_hub_crawler(doi_list, robot_url, user_agent, proxies, num_retries, delay, start_url,useSSL, get_link, nolimit, cache)print('Done.')if __name__ == '__main__':filepath = './data.html' # doi所在的原始 htmlcache_dir = './cache.txt' # 緩存路徑cache = Cache(cache_dir)sci_spider(filepath, nolimit=True, cache=cache)

    4.3 對第一次運行結果的分析與問題處理 ?\star?

    我們運行 sci_spider.py 中的主函數代碼,結束后對結果進行分析。

    4.3.1 運行結果分析

    之前也看到了,一共有 206 個 DOI,這個下載量比較大了,檢查無誤后,我們現在嘗試運行一下:

    trying to collect the doi list... doi_crawler process succeed. now trying to download the pdf files from sci-hub... ... # 下載過程省略 94 of total 206 pdf success Done. time spent: 1664s

    我們可以輕松地從運行結果中提取以下數據:

  • 206 個 doi 中下載成功的有 94 個,占比 45.6%

  • 總共用時為 1664 秒,即 27 分 44 秒,成功下載單個文件的用時為 17.7 秒

  • 另外,我們看看磁盤上的變化:

    cache.txt


    我們注意到最后一個 url 對應第 95 行,而第一個文件從第 2 行開始,所以一共有 94 個 pdf 文件成功下載,從數量上看這是沒有錯的。

    pdf 文件目錄


    驚了,明明成功下載了 94 個,卻只有 71 個項目,難道被誰吃了嗎?確實,看看第一個文件名稱 —— 一個下劃線,這暗示著有些文獻沒抓到標題,標題為空字符,然后這個僅有的空字符被替換成了下劃線,從數目看,空標題的情況有 24 個,數量占比不小了,所以我們得對這些情況下的 html 文本再度分析一下。在此之前,我們再仔細看看運行窗口中那些下載失敗或標題為空的文件對應的輸出信息吧:

    # 第一種類型的錯誤:找不到合適的代理 (不管了) Downloading: https://sci-hub.do/10.11607/ijp.6835 error occurred: list index out of range ... # 第二種類型的錯誤:文件標題抓取為空 (重點關注) Downloading: https://sci-hub.do/10.3390/s20205967 Downloading: https://sci-hub.do/downloads/2020-10-31/dc/10.3390@s20205967.pdf?download=true _.pdf ... # 第三種類型的錯誤:文獻網頁內容為空 (不管了) Downloading: https://sci-hub.do/10.3275/j.cnki.lykxyj.2020.03.013 error occurred: Document is empty ... # 第四種類型的錯誤:原鏈接中已有HTTP協議頭 (重點關注) Downloading: https://sci-hub.do/10.1109/TCIAIG.2017.2755699 Downloading: https:https://twin.sci-hub.do/6601/f481261096492fa7c387e58b490c15c6/llobera2017.pdf?download=true Download error No connection adapters were found for 'https:https://twin.sci-hub.do/6601/f481261096492fa7c387e58b490c15c6/llobera2017.pdf?download=true' ... # 第五種類型的錯誤 :IP被 ACM DL(美國計算機學會 數字圖書館) 官網封禁了, # 但似乎是因為前面加了個 sci-hub 的緣故,去掉后還是可以正常訪問 ACM DL (不管了) Downloading: https://sci-hub.do/10.1145/3337722.3341860 Download error: <html> <head><title>504 Gateway Time-out</title></head> <body> <center><h1>504 Gateway Time-out</h1></center> <hr><center>openresty/1.19.3.1</center> </body> </html># 第六種類型的錯誤:重定向至一個韓國的文獻網站,還要登錄啥的,下不了無所謂了 (不管了) Downloading: https://sci-hub.do/10.5626/JOK.2019.46.11.1157 Download error: <html><head><title>Ошибка: не удалось открыть страницу</title> # 錯誤:無法打開一頁<meta charset="UTF-8"><meta name="viewport" content="width=device-width"></head><body><script type='text/javascript' src='https://check.ddos-guard.net/check.js' async defer></script>...</body> </html> error occurred: expected string or bytes-like object# 第七種類型的錯誤:重定向至一個法國的文獻網站,下不了無所謂了 (不管了) Downloading: https://sci-hub.do/10.16923/reb.v16i1.730 error occurred: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.

    筆者發現了七種不同類型的錯誤信息輸出 (包括空標題),上述出錯的 url 筆者都一一點開過,對于更詳細的錯誤信息,筆者已經在上面作了注釋。下面重點關注兩個比較容易糾正且比較普遍的錯誤:

    • 錯誤類型二:標題抓取為空

    • 錯誤類型四:HTTP協議頭重復

    下面和筆者一起逐個解決~

    4.3.2 問題1:標題抓取為空 —— 用 DOI 作為名字

    點開文獻網址,頁數有點多,加載片刻后如下圖:


    如你所見,我們的目標區域內容為空,那我們得想想別的辦法了?即使不能保證有意義,但最起碼得給它個不一樣的名字,免得造成文件覆蓋而丟失,那我們最容易想到的就是用 DOI 作為名字啦。

    代碼做以下調整:

    download.py

    def download_pdf(result, headers, proxies=None, num_retries=2, doi=None): ···try:...if len(result['title']) < 5: # 處理標題為空的情況filename = get_valid_filename(doi) + '.pdf'else:filename = get_valid_filename(result['title']) + '.pdf'...def sci_hub_crawler(doi_list, robot_url=None, user_agent='sheng', proxies=None,num_retries=2,delay=3, start_url='sci-hub.do', useSSL=True, get_link=None, nolimit=False, cache=None):...if result and download_pdf(result, headers, proxies, num_retries, doi):......

    筆者假定字符數小于 5 時就采用 doi 命名。 (標題至少也得 5 個字符吧)

    4.3.3 問題2:HTTP協議頭重復 —— 添加判斷去重

    點進去一看,有些 onclick 內容中的鏈接自帶HTTP協議頭:

    <a href="#" onclick="location.href= 'https://twin.sci-hub.do/6601/f481261096492fa7c387e58b490c15c6/llobera2017.pdf?download=true'"> ? save</a>

    為此我們需要在代碼中添加一層判斷,首先看看有無HTTP協議頭,如果沒有才添加,修改的代碼如下 (download.py):

    def download_pdf(result, headers, proxies=None, num_retries=2, doi=None):url = result['onclick']components = urlparse(url)if len(components.scheme) == 0: # HTTP協議頭長度為 0,則添加協議頭url = 'https:{}'.format(url)print('Downloading: ', url)... # 小測試 if __name__ == '__main__':from scraping_using_lxml import get_link_xpathdois = ['10.1109/TCIAIG.2017.2755699', # HTTP協議頭重復'10.3390/s20205967', # 標題為空'10.1016/j.apergo.2020.103286' # 沒毛病] get_link = get_link_xpathsci_hub_crawler(dois, get_link = get_link, user_agent='sheng', nolimit=True)print('Done.')

    運行結果:

    Downloading: https://sci-hub.do/10.1109/TCIAIG.2017.2755699 Downloading: https://twin.sci-hub.do/6601/f481261096492fa7c387e58b490c15c6/llobera2017.pdf?download=true A_tool_to_design_interactive_characters_based_on_embodied_cognition. _IEEE_Transactions_on_Computational_Intelligence_and_AI_in_G.pdf Downloading: https://sci-hub.do/10.3390/s20205967 Downloading: https://sci-hub.do/downloads/2020-10-31/dc/10.3390@s20205967.pdf?download=true 10.3390_s20205967.pdf Downloading: https://sci-hub.do/10.1016/j.apergo.2020.103286 Downloading: https://sci-hub.do/downloads/2020-12-01/29/joshi2021.pdf?download=true Implementing_Virtual_Reality_technology_for_safety_training_in_the_precast__ prestressed_concrete_industry._Applied_Ergonomics,_9.pdf 3 of total 3 pdf success Done.

    從運行結果可見,上述問題都已經修復,而且沒有帶來額外的問題 (至少看起來是這樣)。

    4.3.4 最后的調試

    下面我們刪去 cache.txt 和 下載的 pdf (只是測試用的,不要舍不得),再度運行 sci_spider.py,休息半個小時后看看結果:

    trying to collect the doi list... doi_crawler process succeed. now trying to download the pdf files from sci-hub... ... 150 of total 206 pdf success Done. time spent: 2847s

    現在再看看數據,蕪湖,起飛 ~ :

  • 206 個 doi 中下載成功的有 150 個,占比 72.8%

  • 總共用時為 2847 秒,即 47 分 27 秒,成功下載單個文件的用時為 18.98 秒

  • 筆者再此基礎上再運行了一次程序,用以測試緩存功能是否能正常運行,結果符合我們的預期:

    trying to collect the doi list... doi_crawler process succeed. now trying to download the pdf files from sci-hub... ... already downloaded: https:https://twin.sci-hub.do/ 6634/7e804814554806b27952fd2974ae4ba1/radionova2017.pdf?download=true 150 of total 206 pdf success Done. time spent: 1367s

    至此項目結束。

    爬蟲感想

    筆者這次就分享這么多了,一共用了 6 天時間,一邊學,一邊寫博客,一邊碼代碼,花的時間比較長了。文章的長度遠遠超出我的預期,很多東西也就是順著思路寫的,沒怎么整理,筆者想盡可能地還原這個從零到一的過程,不知各位讀者覺得筆者是否做到了呢?

    筆者寫的這個爬蟲十分簡陋,涉及的爬蟲知識也比較淺,爬蟲中對于一些問題的處理也很粗糙,但至少還算能正常工作,可以滿足一定程度的需求。畢竟,筆者接觸爬蟲也就是最近幾個星期,實踐過程中也從各個渠道學到了很多相關的知識,于個人而言已經很滿足了。

    其實在項目執行初期,筆者還有幾個更大的想法,比如,并行下載、將緩存數據存至數據庫 (redis) 、可視化下載進度、做個窗體程序等。但限于時間和篇幅,筆者在此都沒有實現。另外,筆者發現,很多一開始的想法 (在 STEP1 和 STEP2 中提到的),可能到后面都用不上,其中原因的大多是當初調研時考慮不周全。但是,有誰能保證做一個從沒做過的項目時能夠預先進行完美設計呢?完美設計與否,最終還是要靠實踐來檢驗和打磨,代碼從簡單到復雜,再又回到另一個境界的簡單。

    筆者起初打死都想不到,終極接口 sci_spider() 竟然有如此多的參數,看起來相當復雜;但是,它是筆者實踐過程中一步步搭建與優化得到的,就算某個代碼細節忘記了,也有辦法通過重新回顧此代碼而迅速拾起,這或許就是實踐與沒有實踐過的區別。

    筆者是一個無語言論者 (雖然用 C++ 和 C# 比較多),但通過這次實踐,筆者真切感受到了 Python3 的優雅與強大 —— 它將我們從繁雜的語言細節中解放出來,讓我們能集中精力處理去思考問題本身的解決方案。當然,也不能一味地依賴語言帶來的強大功能,對于很多底層原理與細節,如有時間也應該去好好琢磨一下。

    好了,這段爬蟲之旅到此就要畫上句號了。筆者做這個項目的初衷就是為了品嘗用技術解決具體問題的喜悅,現在確實很滿足。然而,凡事都有個主次,筆者還有很多優先級更高的學業任務需要完成,所以可能會有一段時間不碰爬蟲,很高興能分享我的實踐過程,也真心希望這些文字能給您帶來幫助~

    資源 (見GitHub)

    筆者已經把本次實踐的代碼上傳到 GitHub 上了,僅供學習用。如果各位只是想要使用的話,可以在 GitHub 上找到更好的爬蟲。筆者這個用到的知識很少,功能也很簡單,比較 low。

    點此訪問筆者的 GitHub 資源

    References

    筆者把主要的參考文獻放在這里 (有些在文獻中給出了鏈接),有需要的可以自行查閱。

    [1] [德] Katharine Jarmul, 等.用Python寫網絡爬蟲(第二版)[M].李斌, 譯.北京:人民郵電出版社, 2018, pp. 1-78

    [2] 知否知否呀.XPath 選取具有特定文本值的節點[EB/OL].https://blog.csdn.net/lengchun10/article/details/41044119, 2014-11-12.

    [3] 假裝自己是小白.Python中read()、readline()和readlines()三者間的區別和用法[EB/OL].https://www.cnblogs.com/yun1108/p/8967334.html, 2018-04-28.

    [4] dcpeng.手把手教你如何在Pycharm中加載和使用虛擬環境[EB/OL].https://www.cnblogs.com/dcpeng/p/12257331.html, 2020-02-03.

    [5] PilgrimHui.conda環境管理[EB/OL].https://www.cnblogs.com/liaohuiqiang/p/9380417.html, 2018-07-28.

    [6] 奔跑中的兔子.爬蟲之robots.txt[EB/OL].https://www.cnblogs.com/benpao1314/p/11352276.html, 2019-08-14.


    歡迎讀者朋友留言。 如有錯誤請務必批評指正,筆者在此給大佬們抱拳了~

    總結

    以上是生活随笔為你收集整理的【Python爬虫】从零开始爬取Sci-Hub上的论文(串行爬取)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    学生妹亚洲一区二区 | 国产亚洲日韩欧美另类第八页 | 午夜精品久久久久久久久 | 亚洲成色在线综合网站 | 国产午夜亚洲精品不卡 | 少妇性俱乐部纵欲狂欢电影 | aa片在线观看视频在线播放 | 国产69精品久久久久app下载 | 国产精品毛多多水多 | 精品国产一区二区三区av 性色 | 亚洲精品一区三区三区在线观看 | 我要看www免费看插插视频 | 久久99久久99精品中文字幕 | 一本精品99久久精品77 | 天堂а√在线中文在线 | 鲁鲁鲁爽爽爽在线视频观看 | 亚洲人成人无码网www国产 | 真人与拘做受免费视频一 | 亚洲爆乳无码专区 | 成人无码视频免费播放 | 国产精品久久久久无码av色戒 | 亚洲人成人无码网www国产 | 天堂а√在线中文在线 | 熟妇激情内射com | 久久熟妇人妻午夜寂寞影院 | 亚洲日韩一区二区三区 | 国产一区二区不卡老阿姨 | 老司机亚洲精品影院无码 | 亚洲国产成人a精品不卡在线 | 欧美一区二区三区视频在线观看 | www一区二区www免费 | 欧洲熟妇精品视频 | 日韩人妻无码一区二区三区久久99 | 成 人 网 站国产免费观看 | 国产内射老熟女aaaa | 日本乱人伦片中文三区 | 狠狠cao日日穞夜夜穞av | 国产午夜福利100集发布 | 初尝人妻少妇中文字幕 | 亚洲精品国产精品乱码视色 | 老熟妇乱子伦牲交视频 | 在线精品国产一区二区三区 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 欧美国产亚洲日韩在线二区 | 日日干夜夜干 | 国产香蕉尹人综合在线观看 | 精品人妻中文字幕有码在线 | 免费无码午夜福利片69 | 99麻豆久久久国产精品免费 | 131美女爱做视频 | 麻豆国产人妻欲求不满谁演的 | 55夜色66夜色国产精品视频 | 免费国产成人高清在线观看网站 | 国产福利视频一区二区 | 欧美日韩精品 | 国产精品自产拍在线观看 | 大地资源网第二页免费观看 | 国产精品第一国产精品 | 九九热爱视频精品 | 无码av免费一区二区三区试看 | 成人性做爰aaa片免费看不忠 | 婷婷色婷婷开心五月四房播播 | 久久精品成人欧美大片 | 久久久久久国产精品无码下载 | 一本大道久久东京热无码av | 成人欧美一区二区三区黑人免费 | 国产乱人伦av在线无码 | 18精品久久久无码午夜福利 | 国产福利视频一区二区 | 国产免费久久精品国产传媒 | 精品国产一区二区三区四区 | 精品国产福利一区二区 | 帮老师解开蕾丝奶罩吸乳网站 | 黑人玩弄人妻中文在线 | 黑人玩弄人妻中文在线 | www成人国产高清内射 | 在线成人www免费观看视频 | 国产成人综合色在线观看网站 | 中文字幕乱码人妻无码久久 | 日本高清一区免费中文视频 | 欧美放荡的少妇 | 荫蒂添的好舒服视频囗交 | а天堂中文在线官网 | av在线亚洲欧洲日产一区二区 | 天天燥日日燥 | 国产手机在线αⅴ片无码观看 | 久久人妻内射无码一区三区 | 久久综合色之久久综合 | 高潮喷水的毛片 | 99久久精品国产一区二区蜜芽 | 国产午夜无码视频在线观看 | 亚洲成av人片在线观看无码不卡 | 日韩人妻无码中文字幕视频 | 18无码粉嫩小泬无套在线观看 | 99国产欧美久久久精品 | 熟妇女人妻丰满少妇中文字幕 | 性生交片免费无码看人 | av小次郎收藏 | 乱人伦人妻中文字幕无码久久网 | 午夜福利试看120秒体验区 | 欧美高清在线精品一区 | 亚洲a无码综合a国产av中文 | 99久久精品日本一区二区免费 | 国产精品人人爽人人做我的可爱 | 伊人久久大香线蕉午夜 | 300部国产真实乱 | 国产高清av在线播放 | 国产亚洲日韩欧美另类第八页 | 老子影院午夜精品无码 | 99久久婷婷国产综合精品青草免费 | 精品夜夜澡人妻无码av蜜桃 | 国产极品视觉盛宴 | 蜜桃视频韩日免费播放 | 又大又紧又粉嫩18p少妇 | 精品aⅴ一区二区三区 | 国产内射爽爽大片视频社区在线 | 亚洲中文字幕久久无码 | 无码任你躁久久久久久久 | 久久人人爽人人爽人人片av高清 | 亚洲日韩av一区二区三区四区 | 欧美三级不卡在线观看 | 熟妇人妻无码xxx视频 | 欧美老人巨大xxxx做受 | 久久精品国产大片免费观看 | 麻豆av传媒蜜桃天美传媒 | 亚洲精品一区三区三区在线观看 | 野狼第一精品社区 | 人妻体内射精一区二区三四 | 中文字幕无码日韩专区 | 亚洲中文字幕在线无码一区二区 | 兔费看少妇性l交大片免费 | 国产精品久久久av久久久 | 亚洲欧美国产精品久久 | 欧美一区二区三区 | 男女下面进入的视频免费午夜 | 国产一区二区不卡老阿姨 | 欧美日韩综合一区二区三区 | 国产97在线 | 亚洲 | 成人无码精品1区2区3区免费看 | 无码人妻精品一区二区三区下载 | 成熟女人特级毛片www免费 | 国产高清av在线播放 | 亚洲日韩一区二区三区 | 18禁止看的免费污网站 | 亚洲综合无码一区二区三区 | 香蕉久久久久久av成人 | 免费无码的av片在线观看 | 激情内射日本一区二区三区 | 国产人妻精品一区二区三区不卡 | 牲欲强的熟妇农村老妇女视频 | 狠狠综合久久久久综合网 | 欧美国产日韩亚洲中文 | 无码国产激情在线观看 | 无遮挡国产高潮视频免费观看 | 亚洲中文字幕av在天堂 | 国产精品内射视频免费 | 爽爽影院免费观看 | 久久亚洲日韩精品一区二区三区 | 日韩精品一区二区av在线 | 国产精品亚洲综合色区韩国 | 少妇久久久久久人妻无码 | 精品无码国产自产拍在线观看蜜 | 国内精品一区二区三区不卡 | av无码久久久久不卡免费网站 | 中文精品无码中文字幕无码专区 | 国产亚洲精品精品国产亚洲综合 | 无码av免费一区二区三区试看 | 国产色视频一区二区三区 | 精品偷自拍另类在线观看 | 欧美 亚洲 国产 另类 | 国语精品一区二区三区 | 亚洲国产一区二区三区在线观看 | 无码av岛国片在线播放 | 国产后入清纯学生妹 | 国产做国产爱免费视频 | 丰满人妻被黑人猛烈进入 | 亚洲熟悉妇女xxx妇女av | 色欲久久久天天天综合网精品 | 国产精品亚洲专区无码不卡 | 亚洲日韩中文字幕在线播放 | 久久国产精品偷任你爽任你 | 国产成人av免费观看 | 高潮毛片无遮挡高清免费视频 | 久久人妻内射无码一区三区 | 自拍偷自拍亚洲精品10p | aa片在线观看视频在线播放 | 久久精品人妻少妇一区二区三区 | 少妇人妻偷人精品无码视频 | 熟妇人妻无码xxx视频 | 国产办公室秘书无码精品99 | 欧美色就是色 | 日产国产精品亚洲系列 | 内射爽无广熟女亚洲 | 丰满肥臀大屁股熟妇激情视频 | 成人综合网亚洲伊人 | 成人片黄网站色大片免费观看 | 成人亚洲精品久久久久软件 | 国产av无码专区亚洲awww | 国産精品久久久久久久 | 老头边吃奶边弄进去呻吟 | 久久国产36精品色熟妇 | 波多野结衣高清一区二区三区 | 久久99国产综合精品 | 亚洲精品无码人妻无码 | 少妇性l交大片欧洲热妇乱xxx | 亚洲人成人无码网www国产 | 欧美性猛交xxxx富婆 | 久久综合九色综合欧美狠狠 | 97精品国产97久久久久久免费 | 国产成人综合在线女婷五月99播放 | 婷婷丁香五月天综合东京热 | 亚洲国产一区二区三区在线观看 | 国产成人无码a区在线观看视频app | 欧美xxxx黑人又粗又长 | 亚洲а∨天堂久久精品2021 | 在线а√天堂中文官网 | 天堂久久天堂av色综合 | 久久久无码中文字幕久... | 国产真实乱对白精彩久久 | 日日鲁鲁鲁夜夜爽爽狠狠 | 人人妻人人澡人人爽欧美一区 | 亚洲国产精品美女久久久久 | 奇米影视7777久久精品人人爽 | 日本欧美一区二区三区乱码 | 国产av无码专区亚洲a∨毛片 | 日日鲁鲁鲁夜夜爽爽狠狠 | 亚洲国产高清在线观看视频 | 成人精品视频一区二区 | 国产综合在线观看 | 无码人妻少妇伦在线电影 | 大肉大捧一进一出视频出来呀 | 黑人巨大精品欧美黑寡妇 | 国产精品va在线观看无码 | 久久亚洲日韩精品一区二区三区 | 精品国偷自产在线视频 | 国产精品亚洲综合色区韩国 | 日本乱偷人妻中文字幕 | 亚洲色无码一区二区三区 | 久久精品国产日本波多野结衣 | 国产电影无码午夜在线播放 | 欧美成人免费全部网站 | 日日夜夜撸啊撸 | 久久久久亚洲精品男人的天堂 | 久久www免费人成人片 | 老司机亚洲精品影院无码 | 欧美精品在线观看 | 少妇人妻av毛片在线看 | 鲁大师影院在线观看 | 少妇无套内谢久久久久 | 国产亚洲视频中文字幕97精品 | 日本xxxx色视频在线观看免费 | 撕开奶罩揉吮奶头视频 | 午夜福利试看120秒体验区 | 综合激情五月综合激情五月激情1 | 国产一精品一av一免费 | 熟妇人妻激情偷爽文 | 精品偷拍一区二区三区在线看 | 亚洲人成人无码网www国产 | 久久精品国产亚洲精品 | 无码一区二区三区在线观看 | 鲁大师影院在线观看 | 午夜精品一区二区三区在线观看 | 国产内射老熟女aaaa | 老熟妇仑乱视频一区二区 | 高清不卡一区二区三区 | 岛国片人妻三上悠亚 | 日韩欧美成人免费观看 | 久久精品视频在线看15 | v一区无码内射国产 | 波多野结衣高清一区二区三区 | 激情亚洲一区国产精品 | 欧美熟妇另类久久久久久多毛 | 亚洲经典千人经典日产 | 日本大乳高潮视频在线观看 | 最新国产乱人伦偷精品免费网站 | 亚洲中文无码av永久不收费 | 久久综合九色综合欧美狠狠 | 欧美性猛交xxxx富婆 | 亚洲区欧美区综合区自拍区 | 亚洲国产精品毛片av不卡在线 | 国产成人无码av在线影院 | 久久精品国产99久久6动漫 | 女人色极品影院 | 少妇高潮喷潮久久久影院 | 国内精品一区二区三区不卡 | 在线观看国产一区二区三区 | 国产麻豆精品一区二区三区v视界 | 精品久久8x国产免费观看 | 久久久精品456亚洲影院 | 亚洲自偷自偷在线制服 | 久久久久久亚洲精品a片成人 | 精品乱子伦一区二区三区 | 伊人久久婷婷五月综合97色 | 国产成人午夜福利在线播放 | 大肉大捧一进一出好爽视频 | 综合人妻久久一区二区精品 | 亚洲成a人片在线观看无码3d | 综合激情五月综合激情五月激情1 | 久久精品无码一区二区三区 | 国产99久久精品一区二区 | 成人无码视频免费播放 | 国产成人无码午夜视频在线观看 | 在线精品亚洲一区二区 | 丰满人妻翻云覆雨呻吟视频 | 奇米影视7777久久精品人人爽 | 久久久久国色av免费观看性色 | 欧美成人午夜精品久久久 | 丰满少妇弄高潮了www | 熟女体下毛毛黑森林 | 成人性做爰aaa片免费看 | 亚洲小说春色综合另类 | 天天做天天爱天天爽综合网 | 亚洲一区二区三区偷拍女厕 | 全球成人中文在线 | 久久亚洲国产成人精品性色 | 蜜桃臀无码内射一区二区三区 | 欧美性生交xxxxx久久久 | 狠狠色噜噜狠狠狠狠7777米奇 | 夜夜影院未满十八勿进 | 日本大香伊一区二区三区 | 久久精品女人天堂av免费观看 | 国产精品第一国产精品 | 99麻豆久久久国产精品免费 | 动漫av一区二区在线观看 | 亚洲日韩一区二区 | 国产乱人伦av在线无码 | 国产深夜福利视频在线 | 婷婷六月久久综合丁香 | 成人av无码一区二区三区 | 中文字幕av日韩精品一区二区 | 久久这里只有精品视频9 | 精品人妻人人做人人爽 | 欧美人与动性行为视频 | 亚洲欧洲日本综合aⅴ在线 | 欧美自拍另类欧美综合图片区 | 国产精品久久久av久久久 | 国产高潮视频在线观看 | 强辱丰满人妻hd中文字幕 | 少妇厨房愉情理9仑片视频 | 国产精品亚洲а∨无码播放麻豆 | 亚洲色欲色欲欲www在线 | 少女韩国电视剧在线观看完整 | 精品国产一区二区三区四区 | 未满成年国产在线观看 | 国精产品一区二区三区 | 久久久精品人妻久久影视 | 国产美女精品一区二区三区 | 亚洲成色www久久网站 | 日韩欧美中文字幕公布 | 十八禁真人啪啪免费网站 | 水蜜桃亚洲一二三四在线 | 波多野结衣av一区二区全免费观看 | 中文字幕av无码一区二区三区电影 | 永久免费精品精品永久-夜色 | 在线精品亚洲一区二区 | 美女毛片一区二区三区四区 | 国产成人无码区免费内射一片色欲 | 国产suv精品一区二区五 | 国産精品久久久久久久 | 国产乱人伦av在线无码 | 国产亚洲tv在线观看 | 成人无码影片精品久久久 | 麻豆果冻传媒2021精品传媒一区下载 | 夜夜夜高潮夜夜爽夜夜爰爰 | 国产成人综合色在线观看网站 | 精品久久综合1区2区3区激情 | 日韩亚洲欧美精品综合 | 国产精品多人p群无码 | 欧美老熟妇乱xxxxx | 色一情一乱一伦一区二区三欧美 | 亚洲男女内射在线播放 | 亚洲精品成人av在线 | 久久天天躁夜夜躁狠狠 | 国产亚av手机在线观看 | 在线a亚洲视频播放在线观看 | 毛片内射-百度 | 一本一道久久综合久久 | 久久精品国产99久久6动漫 | 久久精品国产大片免费观看 | 亚洲欧美日韩综合久久久 | 亚洲 a v无 码免 费 成 人 a v | 中文无码伦av中文字幕 | 亚洲日韩av一区二区三区四区 | 亚洲精品久久久久avwww潮水 | 欧洲欧美人成视频在线 | 日本在线高清不卡免费播放 | 扒开双腿吃奶呻吟做受视频 | 在线成人www免费观看视频 | 精品久久久中文字幕人妻 | 国产区女主播在线观看 | 97精品国产97久久久久久免费 | 欧美freesex黑人又粗又大 | 亚洲中文字幕无码中文字在线 | 国产特级毛片aaaaaaa高清 | 国产超级va在线观看视频 | 伊人久久大香线焦av综合影院 | 久久国产劲爆∧v内射 | 国内丰满熟女出轨videos | 色综合久久中文娱乐网 | 亚洲综合另类小说色区 | 国产无av码在线观看 | 女人被爽到呻吟gif动态图视看 | 日本乱人伦片中文三区 | 亚洲成a人一区二区三区 | 四虎4hu永久免费 | 午夜免费福利小电影 | 亚洲成av人在线观看网址 | 欧美老人巨大xxxx做受 | 国产成人无码av在线影院 | 国产成人无码区免费内射一片色欲 | 国产成人综合色在线观看网站 | 丰满人妻一区二区三区免费视频 | 欧美性生交xxxxx久久久 | 久久精品99久久香蕉国产色戒 | 欧美亚洲日韩国产人成在线播放 | √天堂资源地址中文在线 | 无码纯肉视频在线观看 | 东京热一精品无码av | 亚洲日本va午夜在线电影 | 欧美精品无码一区二区三区 | 成年美女黄网站色大免费全看 | 中文字幕无码日韩专区 | 久久久中文字幕日本无吗 | 亚洲爆乳精品无码一区二区三区 | 中文字幕人成乱码熟女app | 亚洲一区二区三区香蕉 | 亚洲综合无码久久精品综合 | 奇米影视7777久久精品人人爽 | 亚洲欧美精品伊人久久 | 大屁股大乳丰满人妻 | 强辱丰满人妻hd中文字幕 | www一区二区www免费 | 免费无码av一区二区 | 乱人伦人妻中文字幕无码 | 曰韩少妇内射免费播放 | 伊人久久大香线蕉亚洲 | 婷婷丁香五月天综合东京热 | 亚洲日韩av一区二区三区中文 | 日本成熟视频免费视频 | 久久99热只有频精品8 | 欧美高清在线精品一区 | 国产精品对白交换视频 | 久久久久国色av免费观看性色 | 欧美精品国产综合久久 | 97久久精品无码一区二区 | 荫蒂被男人添的好舒服爽免费视频 | 夜夜高潮次次欢爽av女 | 亚洲人成网站在线播放942 | 99久久无码一区人妻 | 无码人中文字幕 | 日日摸天天摸爽爽狠狠97 | 国产疯狂伦交大片 | 久久精品一区二区三区四区 | 欧美兽交xxxx×视频 | 亚洲春色在线视频 | 精品国产一区二区三区av 性色 | 日日摸夜夜摸狠狠摸婷婷 | 国内精品九九久久久精品 | 又粗又大又硬又长又爽 | 亚洲人交乣女bbw | 中文毛片无遮挡高清免费 | 人妻少妇被猛烈进入中文字幕 | 久久国产36精品色熟妇 | 亚洲精品成人福利网站 | 国产福利视频一区二区 | 亚洲男人av天堂午夜在 | 国产成人无码a区在线观看视频app | 亚洲精品综合一区二区三区在线 | 国产女主播喷水视频在线观看 | 天天av天天av天天透 | 帮老师解开蕾丝奶罩吸乳网站 | 99国产精品白浆在线观看免费 | www一区二区www免费 | 国产三级久久久精品麻豆三级 | 日韩精品一区二区av在线 | 99久久99久久免费精品蜜桃 | 图片小说视频一区二区 | 国内揄拍国内精品人妻 | 精品久久久无码人妻字幂 | 狂野欧美性猛交免费视频 | 国产人成高清在线视频99最全资源 | 97资源共享在线视频 | 在线精品亚洲一区二区 | 国产成人无码一二三区视频 | 精品久久久无码人妻字幂 | 成人精品视频一区二区 | 中文字幕乱码人妻无码久久 | 国产疯狂伦交大片 | 俄罗斯老熟妇色xxxx | 亚洲国产精品一区二区美利坚 | 99国产精品白浆在线观看免费 | 国产精品久久精品三级 | 狠狠色噜噜狠狠狠7777奇米 | 国产三级精品三级男人的天堂 | 国产av一区二区三区最新精品 | 精品国产成人一区二区三区 | 欧洲美熟女乱又伦 | 九九热爱视频精品 | 日韩精品成人一区二区三区 | 澳门永久av免费网站 | 欧美午夜特黄aaaaaa片 | 鲁鲁鲁爽爽爽在线视频观看 | 无人区乱码一区二区三区 | 99re在线播放 | 午夜成人1000部免费视频 | 欧美成人免费全部网站 | 狠狠色噜噜狠狠狠7777奇米 | 亚洲国产成人av在线观看 | 国产凸凹视频一区二区 | 伊在人天堂亚洲香蕉精品区 | 男女爱爱好爽视频免费看 | 亚洲色大成网站www国产 | 久久精品一区二区三区四区 | 色欲人妻aaaaaaa无码 | 精品午夜福利在线观看 | 亚洲精品一区二区三区在线观看 | 成 人 免费观看网站 | 小泽玛莉亚一区二区视频在线 | 国产人妻精品一区二区三区 | 国产成人综合色在线观看网站 | 免费乱码人妻系列无码专区 | yw尤物av无码国产在线观看 | 最新版天堂资源中文官网 | 少女韩国电视剧在线观看完整 | 老熟女重囗味hdxx69 | 天天摸天天碰天天添 | 亚洲欧美色中文字幕在线 | 亚洲国产日韩a在线播放 | 精品欧洲av无码一区二区三区 | 色噜噜亚洲男人的天堂 | 中文字幕无码热在线视频 | www国产精品内射老师 | 久久国产劲爆∧v内射 | 欧美日韩综合一区二区三区 | 在线观看国产一区二区三区 | 无套内谢的新婚少妇国语播放 | 综合激情五月综合激情五月激情1 | 国产精品久久久av久久久 | 色综合久久88色综合天天 | 国产精品免费大片 | 欧美日韩一区二区免费视频 | 无人区乱码一区二区三区 | 国产午夜无码视频在线观看 | 极品尤物被啪到呻吟喷水 | 亚洲阿v天堂在线 | 免费网站看v片在线18禁无码 | 日韩人妻无码一区二区三区久久99 | 国产成人无码专区 | 日日天干夜夜狠狠爱 | 纯爱无遮挡h肉动漫在线播放 | 亚洲日本一区二区三区在线 | 少妇高潮喷潮久久久影院 | 又粗又大又硬毛片免费看 | 一个人免费观看的www视频 | 麻豆果冻传媒2021精品传媒一区下载 | 亚洲理论电影在线观看 | 无码国模国产在线观看 | 夜精品a片一区二区三区无码白浆 | 99久久亚洲精品无码毛片 | 久久人人爽人人人人片 | 鲁大师影院在线观看 | 国产超级va在线观看视频 | 领导边摸边吃奶边做爽在线观看 | 曰韩无码二三区中文字幕 | 久久精品国产亚洲精品 | 国产成人综合在线女婷五月99播放 | 国产成人无码a区在线观看视频app | 女人被男人躁得好爽免费视频 | 国产成人无码a区在线观看视频app | 人人澡人人透人人爽 | v一区无码内射国产 | 午夜精品久久久久久久久 | 奇米影视7777久久精品 | 成人无码精品一区二区三区 | 国产成人人人97超碰超爽8 | 动漫av一区二区在线观看 | 中文字幕日产无线码一区 | 77777熟女视频在线观看 а天堂中文在线官网 | 欧美熟妇另类久久久久久多毛 | 欧美性猛交xxxx富婆 | 欧美日韩在线亚洲综合国产人 | 日韩在线不卡免费视频一区 | 乱码av麻豆丝袜熟女系列 | 国产农村乱对白刺激视频 | 两性色午夜视频免费播放 | 久久精品视频在线看15 | 天堂久久天堂av色综合 | 东京热无码av男人的天堂 | 小sao货水好多真紧h无码视频 | 在线观看欧美一区二区三区 | 夜夜高潮次次欢爽av女 | 天天拍夜夜添久久精品大 | 成熟女人特级毛片www免费 | 午夜精品一区二区三区在线观看 | 人人澡人人妻人人爽人人蜜桃 | 久久综合给久久狠狠97色 | 中文字幕人妻丝袜二区 | 无遮挡啪啪摇乳动态图 | 蜜桃无码一区二区三区 | 日产精品高潮呻吟av久久 | 中文无码成人免费视频在线观看 | 日韩精品a片一区二区三区妖精 | 一区二区三区乱码在线 | 欧洲 | 亚洲区欧美区综合区自拍区 | 麻花豆传媒剧国产免费mv在线 | 97夜夜澡人人双人人人喊 | 少妇人妻偷人精品无码视频 | 日韩av无码一区二区三区 | 国产精品对白交换视频 | 亚洲精品中文字幕乱码 | 国产精品无套呻吟在线 | 国产三级久久久精品麻豆三级 | 国产精品久久久久久久9999 | 国产麻豆精品一区二区三区v视界 | 三上悠亚人妻中文字幕在线 | 亚洲 日韩 欧美 成人 在线观看 | 51国偷自产一区二区三区 | 久久综合网欧美色妞网 | 无码国内精品人妻少妇 | 欧美精品一区二区精品久久 | 天堂无码人妻精品一区二区三区 | 午夜熟女插插xx免费视频 | 熟妇人妻中文av无码 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 老太婆性杂交欧美肥老太 | 77777熟女视频在线观看 а天堂中文在线官网 | 大屁股大乳丰满人妻 | 亚洲国产欧美国产综合一区 | 奇米影视888欧美在线观看 | 捆绑白丝粉色jk震动捧喷白浆 | 无码av免费一区二区三区试看 | 性生交大片免费看l | 亚洲日本va中文字幕 | 精品国产一区二区三区四区 | 97精品人妻一区二区三区香蕉 | 亚洲日韩av一区二区三区中文 | 免费乱码人妻系列无码专区 | 白嫩日本少妇做爰 | 男人的天堂av网站 | 日日橹狠狠爱欧美视频 | 自拍偷自拍亚洲精品被多人伦好爽 | √8天堂资源地址中文在线 | 福利一区二区三区视频在线观看 | 玩弄少妇高潮ⅹxxxyw | 亚洲无人区午夜福利码高清完整版 | 无码乱肉视频免费大全合集 | 99久久精品午夜一区二区 | 999久久久国产精品消防器材 | 国产免费久久精品国产传媒 | 小鲜肉自慰网站xnxx | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 一个人看的www免费视频在线观看 | 久久久中文字幕日本无吗 | 玩弄中年熟妇正在播放 | 国产片av国语在线观看 | 国精品人妻无码一区二区三区蜜柚 | 青青久在线视频免费观看 | 久久国产精品偷任你爽任你 | 久久99精品久久久久久 | 中文字幕无码av波多野吉衣 | 乱人伦中文视频在线观看 | 东京热一精品无码av | 久久久久成人精品免费播放动漫 | 国产成人精品优优av | 精品人妻人人做人人爽 | 野外少妇愉情中文字幕 | 麻豆av传媒蜜桃天美传媒 | 又粗又大又硬毛片免费看 | 又大又黄又粗又爽的免费视频 | 色综合久久久无码中文字幕 | 久久久久se色偷偷亚洲精品av | 久久久久久a亚洲欧洲av冫 | 中文字幕 人妻熟女 | 欧美人与善在线com | 亚洲综合久久一区二区 | 亚欧洲精品在线视频免费观看 | 国产福利视频一区二区 | 久久综合久久自在自线精品自 | 中文字幕人成乱码熟女app | 国内老熟妇对白xxxxhd | 国产精品第一区揄拍无码 | 一本色道久久综合亚洲精品不卡 | 水蜜桃色314在线观看 | 久久久精品国产sm最大网站 | 亚洲人成网站在线播放942 | 国产一区二区三区四区五区加勒比 | 成熟妇人a片免费看网站 | 天天av天天av天天透 | 国产又爽又猛又粗的视频a片 | 久久午夜无码鲁丝片 | 国产尤物精品视频 | 人妻互换免费中文字幕 | 日韩欧美中文字幕公布 | 亚洲综合在线一区二区三区 | 内射老妇bbwx0c0ck | 欧美35页视频在线观看 | 欧美 丝袜 自拍 制服 另类 | 久激情内射婷内射蜜桃人妖 | 国产激情无码一区二区app | 欧美丰满熟妇xxxx | 国产成人午夜福利在线播放 | 久久久久久av无码免费看大片 | 蜜桃臀无码内射一区二区三区 | 永久免费精品精品永久-夜色 | 成人无码精品一区二区三区 | 久久久久国色av免费观看性色 | 亚洲区小说区激情区图片区 | 欧美老妇与禽交 | 在线播放无码字幕亚洲 | 无码人妻av免费一区二区三区 | www国产亚洲精品久久网站 | 中文字幕日韩精品一区二区三区 | 中文字幕无码免费久久9一区9 | 成在人线av无码免观看麻豆 | 亚洲精品中文字幕乱码 | 天天摸天天碰天天添 | 99久久无码一区人妻 | 熟女体下毛毛黑森林 | 久久精品国产日本波多野结衣 | 国产av无码专区亚洲awww | 色诱久久久久综合网ywww | 扒开双腿吃奶呻吟做受视频 | 精品成在人线av无码免费看 | 国产色xx群视频射精 | 亚洲小说春色综合另类 | 色一情一乱一伦一视频免费看 | 爆乳一区二区三区无码 | 亚洲综合无码一区二区三区 | 久久久久久亚洲精品a片成人 | 中国大陆精品视频xxxx | 在线观看国产午夜福利片 | 久久亚洲a片com人成 | 午夜无码人妻av大片色欲 | 青草青草久热国产精品 | 中国女人内谢69xxxx | 精品国产aⅴ无码一区二区 | 无遮挡啪啪摇乳动态图 | 大胆欧美熟妇xx | 国产高潮视频在线观看 | 熟女少妇人妻中文字幕 | 国产激情艳情在线看视频 | 国产真实夫妇视频 | 久久精品中文字幕一区 | 少妇太爽了在线观看 | 国产亚洲精品久久久ai换 | 色婷婷欧美在线播放内射 | 无码国内精品人妻少妇 | 亚欧洲精品在线视频免费观看 | 国内精品一区二区三区不卡 | 久久久国产一区二区三区 | 国产色视频一区二区三区 | 亚洲成a人片在线观看日本 | 久久精品无码一区二区三区 | 精品国产福利一区二区 | 丰满少妇熟乱xxxxx视频 | 天堂无码人妻精品一区二区三区 | 日本护士xxxxhd少妇 | 亚洲男女内射在线播放 | 国产电影无码午夜在线播放 | 国产明星裸体无码xxxx视频 | 亲嘴扒胸摸屁股激烈网站 | 精品水蜜桃久久久久久久 | 久久精品一区二区三区四区 | 精品亚洲成av人在线观看 | 中文字幕乱码人妻二区三区 | 老太婆性杂交欧美肥老太 | 国产人妻久久精品二区三区老狼 | 中文字幕乱码人妻二区三区 | 牲欲强的熟妇农村老妇女视频 | 综合人妻久久一区二区精品 | 2020最新国产自产精品 | 中文字幕乱码人妻无码久久 | 精品国偷自产在线视频 | 日韩精品久久久肉伦网站 | 国产精品亚洲一区二区三区喷水 | 扒开双腿疯狂进出爽爽爽视频 | 国产麻豆精品一区二区三区v视界 | 最近中文2019字幕第二页 | 少妇一晚三次一区二区三区 | 老子影院午夜精品无码 | 久久国产精品萌白酱免费 | 在线а√天堂中文官网 | 丰满少妇高潮惨叫视频 | 玩弄少妇高潮ⅹxxxyw | 内射爽无广熟女亚洲 | 欧美熟妇另类久久久久久多毛 | 亚洲精品成人av在线 | 搡女人真爽免费视频大全 | 国产午夜手机精彩视频 | 欧美日韩色另类综合 | 久久99精品久久久久久动态图 | 欧美日韩在线亚洲综合国产人 | 日本xxxx色视频在线观看免费 | 国产精品人人爽人人做我的可爱 | aⅴ亚洲 日韩 色 图网站 播放 | 日本肉体xxxx裸交 | 精品成人av一区二区三区 | 亚洲毛片av日韩av无码 | 成人免费视频一区二区 | 国产精品视频免费播放 | 成年美女黄网站色大免费全看 | 免费男性肉肉影院 | 亚洲国产欧美日韩精品一区二区三区 | 天天综合网天天综合色 | 无码av最新清无码专区吞精 | 大胆欧美熟妇xx | 亚洲国产精品美女久久久久 | 国产真实夫妇视频 | 国产综合在线观看 | 国产在线精品一区二区高清不卡 | 国产午夜视频在线观看 | 久久99精品国产麻豆蜜芽 | 国产成人综合在线女婷五月99播放 | 麻豆果冻传媒2021精品传媒一区下载 | 中文字幕av日韩精品一区二区 | √天堂资源地址中文在线 | 激情内射亚州一区二区三区爱妻 | 少妇激情av一区二区 | 蜜桃av抽搐高潮一区二区 | 天下第一社区视频www日本 | 少妇愉情理伦片bd | 欧美日韩色另类综合 | 日本一卡二卡不卡视频查询 | 无人区乱码一区二区三区 | 日本饥渴人妻欲求不满 | 久久精品国产一区二区三区肥胖 | 性色av无码免费一区二区三区 | 久久久成人毛片无码 | 亚洲乱亚洲乱妇50p | 中文字幕+乱码+中文字幕一区 | 午夜福利电影 | 日韩无套无码精品 | 国产精品人人爽人人做我的可爱 | 国产成人无码av在线影院 | 成人精品一区二区三区中文字幕 | 在线播放免费人成毛片乱码 | 人妻插b视频一区二区三区 | 日韩人妻无码一区二区三区久久99 | 无码播放一区二区三区 | 给我免费的视频在线观看 | 九九综合va免费看 | 久久精品国产99久久6动漫 | 无码午夜成人1000部免费视频 | 乱人伦人妻中文字幕无码久久网 | 久久精品国产99久久6动漫 | 欧美野外疯狂做受xxxx高潮 | 国产成人精品久久亚洲高清不卡 | 国内精品人妻无码久久久影院 | 国产黑色丝袜在线播放 | 久久国产精品偷任你爽任你 | 中文字幕人成乱码熟女app | 999久久久国产精品消防器材 | 久久久国产一区二区三区 | 亚洲自偷自拍另类第1页 | 国产成人人人97超碰超爽8 | 国产黑色丝袜在线播放 | 最新国产麻豆aⅴ精品无码 | 亚洲精品成a人在线观看 | 欧美亚洲日韩国产人成在线播放 | 中文字幕精品av一区二区五区 | 97色伦图片97综合影院 | 亚洲七七久久桃花影院 | 久久天天躁狠狠躁夜夜免费观看 | 国产 浪潮av性色四虎 | 午夜福利不卡在线视频 | 国色天香社区在线视频 | 欧美丰满熟妇xxxx | 亚洲日本一区二区三区在线 | 人人爽人人爽人人片av亚洲 | 中文无码精品a∨在线观看不卡 | 国内精品久久久久久中文字幕 | 丝袜人妻一区二区三区 | 亚洲精品中文字幕乱码 | 中文字幕人妻无码一区二区三区 | 久久国产精品精品国产色婷婷 | 国产内射爽爽大片视频社区在线 | 日本成熟视频免费视频 | 女人被爽到呻吟gif动态图视看 | 色婷婷香蕉在线一区二区 | 少妇久久久久久人妻无码 | 九九久久精品国产免费看小说 | 国产特级毛片aaaaaa高潮流水 | 精品国精品国产自在久国产87 | 永久免费观看国产裸体美女 | 在教室伦流澡到高潮hnp视频 | 亚洲熟妇色xxxxx欧美老妇 | 亚洲国产综合无码一区 | 亚洲爆乳大丰满无码专区 | 国产精品久久国产三级国 | 野外少妇愉情中文字幕 | 精品国产一区二区三区av 性色 | 国产人妻精品一区二区三区不卡 | 国产特级毛片aaaaaaa高清 | 国产精品丝袜黑色高跟鞋 | 欧美一区二区三区视频在线观看 | 中文字幕乱码人妻无码久久 | 青青久在线视频免费观看 | 伊人久久大香线蕉午夜 | 午夜福利试看120秒体验区 | 无码人妻精品一区二区三区不卡 | а√天堂www在线天堂小说 | 亚洲热妇无码av在线播放 | 成人无码精品一区二区三区 | 国产香蕉尹人视频在线 | 亚洲精品欧美二区三区中文字幕 | 欧美日韩人成综合在线播放 | 欧美日韩色另类综合 | 任你躁在线精品免费 | 99视频精品全部免费免费观看 | 日日天干夜夜狠狠爱 | 亚洲毛片av日韩av无码 | 亚洲精品一区三区三区在线观看 | 欧美老妇交乱视频在线观看 | 国产色精品久久人妻 | 免费观看黄网站 | 欧美怡红院免费全部视频 | 国产精品嫩草久久久久 | 国产精品理论片在线观看 | 精品无码一区二区三区爱欲 | 亚洲欧洲中文日韩av乱码 | 欧美freesex黑人又粗又大 | 撕开奶罩揉吮奶头视频 | 日日干夜夜干 | 久久久久亚洲精品男人的天堂 | 男女作爱免费网站 | 青草青草久热国产精品 | 51国偷自产一区二区三区 | 亚洲欧美日韩综合久久久 | 色综合久久久久综合一本到桃花网 | 日韩人妻少妇一区二区三区 | 亚洲一区二区三区 | 中文字幕无码日韩专区 | 亚洲aⅴ无码成人网站国产app | 一本大道伊人av久久综合 | 无码午夜成人1000部免费视频 | 天堂а√在线地址中文在线 | 少妇太爽了在线观看 | 日韩精品无码一区二区中文字幕 | 国产在线aaa片一区二区99 | 亚洲の无码国产の无码影院 | 5858s亚洲色大成网站www | 久久久久久久久888 | 久久人人97超碰a片精品 | 免费无码午夜福利片69 | 久久综合给合久久狠狠狠97色 | 老熟女重囗味hdxx69 | 最新国产乱人伦偷精品免费网站 | 成人一在线视频日韩国产 | 国产热a欧美热a在线视频 | аⅴ资源天堂资源库在线 | 久久久久久国产精品无码下载 | 亚洲欧美国产精品专区久久 | 人妻少妇精品视频专区 | 永久免费观看国产裸体美女 | 两性色午夜免费视频 | 亚洲国产午夜精品理论片 | 亚洲色在线无码国产精品不卡 | 中国女人内谢69xxxx | 成人欧美一区二区三区黑人免费 | 鲁一鲁av2019在线 | 亚洲国产综合无码一区 | 精品久久久中文字幕人妻 | 樱花草在线播放免费中文 | 色狠狠av一区二区三区 | 国产极品美女高潮无套在线观看 | 亚洲va欧美va天堂v国产综合 | 久久99热只有频精品8 | 国产精品无套呻吟在线 | 国产人妻大战黑人第1集 | 99精品国产综合久久久久五月天 | 男女爱爱好爽视频免费看 | 亚洲a无码综合a国产av中文 | 又色又爽又黄的美女裸体网站 | 日本熟妇乱子伦xxxx | 亚洲精品鲁一鲁一区二区三区 | 亚洲а∨天堂久久精品2021 | 97se亚洲精品一区 | 一本色道久久综合狠狠躁 | 99久久99久久免费精品蜜桃 | 强辱丰满人妻hd中文字幕 | 日韩少妇内射免费播放 | 人妻少妇精品视频专区 | 久久亚洲a片com人成 | 中文字幕av无码一区二区三区电影 | 久久久久成人精品免费播放动漫 | 98国产精品综合一区二区三区 | 久久99久久99精品中文字幕 | 18禁黄网站男男禁片免费观看 | 久久人人爽人人人人片 | 永久免费观看国产裸体美女 | 一区二区三区乱码在线 | 欧洲 | 国产成人精品久久亚洲高清不卡 | 中文字幕精品av一区二区五区 | 国产精品视频免费播放 | 国产免费无码一区二区视频 | 女人和拘做爰正片视频 | www一区二区www免费 | 97人妻精品一区二区三区 | 色婷婷香蕉在线一区二区 | 国产精品18久久久久久麻辣 | 久久综合色之久久综合 | 十八禁真人啪啪免费网站 | 欧美野外疯狂做受xxxx高潮 | 男女爱爱好爽视频免费看 | 呦交小u女精品视频 | 亚洲欧美精品aaaaaa片 | 亚洲午夜福利在线观看 | 久久综合给久久狠狠97色 | 亚洲国产成人av在线观看 | 99国产精品白浆在线观看免费 | 国产亚洲精品久久久久久 | 麻豆国产丝袜白领秘书在线观看 | 亚洲综合在线一区二区三区 | 久久99精品国产麻豆 | 国产九九九九九九九a片 | 亚洲国产精华液网站w | 麻豆国产人妻欲求不满谁演的 | 2020久久超碰国产精品最新 | 天天做天天爱天天爽综合网 | 老子影院午夜精品无码 | 久9re热视频这里只有精品 | 国产明星裸体无码xxxx视频 | 欧美精品免费观看二区 | 国产一区二区三区日韩精品 | 天海翼激烈高潮到腰振不止 | 欧美xxxx黑人又粗又长 | 国产乱人无码伦av在线a | 久久综合香蕉国产蜜臀av | 无码av岛国片在线播放 | 中文字幕无码日韩专区 | 中文字幕乱码中文乱码51精品 | 国内丰满熟女出轨videos | 欧美性黑人极品hd | 亚洲欧洲无卡二区视頻 | 桃花色综合影院 | 少女韩国电视剧在线观看完整 | 久久亚洲中文字幕精品一区 | 精品无码一区二区三区爱欲 | 人人妻人人澡人人爽欧美一区 | 亚洲色在线无码国产精品不卡 | 亚洲日本va中文字幕 | 久久人妻内射无码一区三区 | 一本色道久久综合狠狠躁 | 在线天堂新版最新版在线8 | www国产亚洲精品久久久日本 | 亚洲中文字幕无码中文字在线 | 国产麻豆精品一区二区三区v视界 | 日本精品人妻无码77777 天堂一区人妻无码 | 女人和拘做爰正片视频 | 免费无码一区二区三区蜜桃大 | 欧美三级不卡在线观看 | 中文字幕人妻无码一夲道 | 国产福利视频一区二区 | 无码国产激情在线观看 | 又紧又大又爽精品一区二区 | 色综合久久久无码中文字幕 | 国产乡下妇女做爰 | 国精产品一品二品国精品69xx | 中文无码精品a∨在线观看不卡 | 国产绳艺sm调教室论坛 | 捆绑白丝粉色jk震动捧喷白浆 | 无码人妻精品一区二区三区下载 | 大肉大捧一进一出好爽视频 | 在线观看免费人成视频 | 精品久久久无码中文字幕 | 中文字幕av无码一区二区三区电影 | 国产精品多人p群无码 | 久久亚洲a片com人成 | 亚洲精品久久久久久一区二区 | 狂野欧美激情性xxxx | 四虎永久在线精品免费网址 | 国产两女互慰高潮视频在线观看 | 国产精品无码永久免费888 | 青春草在线视频免费观看 | 波多野结衣高清一区二区三区 | 黄网在线观看免费网站 | 日本精品人妻无码77777 天堂一区人妻无码 | 国产另类ts人妖一区二区 | 欧美精品一区二区精品久久 | 国产成人无码a区在线观看视频app | 国产精品美女久久久 | 国产九九九九九九九a片 | 日本在线高清不卡免费播放 | 精品亚洲成av人在线观看 | 国产亚洲精品久久久久久久 | 国产美女极度色诱视频www | 麻豆成人精品国产免费 | 久久综合激激的五月天 | 国产日产欧产精品精品app | 亚洲欧洲日本无在线码 | 两性色午夜视频免费播放 | 老子影院午夜伦不卡 | 亚洲国产成人av在线观看 | 欧美肥老太牲交大战 | 成人免费视频一区二区 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 国内精品人妻无码久久久影院蜜桃 | 一本大道久久东京热无码av | 在教室伦流澡到高潮hnp视频 | 秋霞成人午夜鲁丝一区二区三区 | 亚洲日韩乱码中文无码蜜桃臀网站 | 色婷婷综合激情综在线播放 | 在教室伦流澡到高潮hnp视频 | 精品人妻av区 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 男女性色大片免费网站 | 国产精品福利视频导航 | 在线视频网站www色 | 亚洲成色www久久网站 | 精品成在人线av无码免费看 | 图片小说视频一区二区 | 国产精品美女久久久久av爽李琼 | 亚洲精品一区二区三区在线观看 | 中文字幕精品av一区二区五区 | 老司机亚洲精品影院无码 | 牲欲强的熟妇农村老妇女 | 欧美日韩视频无码一区二区三 | 亚洲第一无码av无码专区 | 六月丁香婷婷色狠狠久久 | 久久久久亚洲精品男人的天堂 | 思思久久99热只有频精品66 | 天堂亚洲2017在线观看 | 精品久久综合1区2区3区激情 | 亚洲精品中文字幕久久久久 | 国产区女主播在线观看 | 无码纯肉视频在线观看 | 女高中生第一次破苞av | 亚洲另类伦春色综合小说 | 老熟妇仑乱视频一区二区 | 亚洲精品国产a久久久久久 | 国内老熟妇对白xxxxhd | 日日噜噜噜噜夜夜爽亚洲精品 | 精品日本一区二区三区在线观看 | 天干天干啦夜天干天2017 | 少妇性荡欲午夜性开放视频剧场 | 午夜性刺激在线视频免费 | 亚洲精品国偷拍自产在线观看蜜桃 | 欧美日韩亚洲国产精品 | 午夜福利电影 | 纯爱无遮挡h肉动漫在线播放 | 国产精品人妻一区二区三区四 | 亚洲娇小与黑人巨大交 | 精品夜夜澡人妻无码av蜜桃 | 天下第一社区视频www日本 | 国产精品手机免费 | 夜夜高潮次次欢爽av女 | 97夜夜澡人人爽人人喊中国片 | 99麻豆久久久国产精品免费 | 国产精品无码mv在线观看 | 欧美喷潮久久久xxxxx | 久久国产精品_国产精品 | 精品亚洲韩国一区二区三区 | 国产精品久久久久久无码 | 午夜精品一区二区三区的区别 | 国产精品99久久精品爆乳 | 少妇高潮一区二区三区99 | 久久综合色之久久综合 | 亚洲成av人片天堂网无码】 | 99久久99久久免费精品蜜桃 | 全球成人中文在线 | 又粗又大又硬又长又爽 | 精品国产乱码久久久久乱码 | 国产精品无码mv在线观看 | 午夜肉伦伦影院 | 日韩人妻无码一区二区三区久久99 | 欧美国产日韩久久mv | 人人妻人人澡人人爽欧美一区九九 | 红桃av一区二区三区在线无码av | 免费无码午夜福利片69 | 中文字幕av伊人av无码av | 在线天堂新版最新版在线8 | 窝窝午夜理论片影院 | 国产成人亚洲综合无码 | 亚洲欧洲日本综合aⅴ在线 | 熟女少妇人妻中文字幕 | 亚洲狠狠色丁香婷婷综合 | 成人毛片一区二区 | 中文字幕无码视频专区 | 亚洲人亚洲人成电影网站色 | 国产精品va在线观看无码 | 人妻无码αv中文字幕久久琪琪布 | 久久久久亚洲精品男人的天堂 | 好屌草这里只有精品 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 成人试看120秒体验区 | 熟妇人妻中文av无码 | 老熟女重囗味hdxx69 | 亚洲成a人片在线观看日本 | 少妇无套内谢久久久久 | 少妇性荡欲午夜性开放视频剧场 | 人人妻人人澡人人爽精品欧美 | 国产精品久久久午夜夜伦鲁鲁 | 久久精品国产一区二区三区肥胖 | 国内揄拍国内精品少妇国语 | 一本无码人妻在中文字幕免费 | 亚洲精品鲁一鲁一区二区三区 | 丰满少妇弄高潮了www | 精品成在人线av无码免费看 | 无码人妻精品一区二区三区下载 | 扒开双腿吃奶呻吟做受视频 | 国产麻豆精品一区二区三区v视界 | 真人与拘做受免费视频一 | 精品人人妻人人澡人人爽人人 | 国产成人无码午夜视频在线观看 | 超碰97人人射妻 | 久久久久se色偷偷亚洲精品av | 色噜噜亚洲男人的天堂 | 国产精品怡红院永久免费 | 久久精品人人做人人综合 | 一本久道久久综合婷婷五月 | 日本精品高清一区二区 | 中文毛片无遮挡高清免费 | 成人欧美一区二区三区 | 国产香蕉97碰碰久久人人 | 熟女少妇在线视频播放 | 夫妻免费无码v看片 | 久久久久人妻一区精品色欧美 | 18无码粉嫩小泬无套在线观看 | 麻豆人妻少妇精品无码专区 | 中文字幕 亚洲精品 第1页 | 亚洲中文字幕乱码av波多ji | 荫蒂被男人添的好舒服爽免费视频 | 性色欲情网站iwww九文堂 | 国产成人精品无码播放 | 熟妇人妻无乱码中文字幕 | 天堂а√在线地址中文在线 | 澳门永久av免费网站 | 久9re热视频这里只有精品 | 国产精华av午夜在线观看 | 国产福利视频一区二区 | 巨爆乳无码视频在线观看 | 午夜成人1000部免费视频 | 国产午夜福利100集发布 | 精品国产国产综合精品 | 黑人巨大精品欧美黑寡妇 | 丝袜足控一区二区三区 | 国产猛烈高潮尖叫视频免费 | 精品无码国产自产拍在线观看蜜 | 国产精品亚洲一区二区三区喷水 | 国产亚洲精品精品国产亚洲综合 | 亚洲欧美国产精品专区久久 | 乱码午夜-极国产极内射 | 免费视频欧美无人区码 | 中文字幕 人妻熟女 | 狠狠综合久久久久综合网 | 久久精品人人做人人综合 | 精品aⅴ一区二区三区 | 色老头在线一区二区三区 | 成人动漫在线观看 | 亚洲中文字幕无码中字 | 国产精品理论片在线观看 | 又湿又紧又大又爽a视频国产 | 欧美第一黄网免费网站 | 亚洲国产午夜精品理论片 | 男人扒开女人内裤强吻桶进去 | 国产另类ts人妖一区二区 | 熟妇人妻无乱码中文字幕 | 日日夜夜撸啊撸 | 99麻豆久久久国产精品免费 | 黑人巨大精品欧美黑寡妇 | 久久99久久99精品中文字幕 | 亚洲色成人中文字幕网站 | 牛和人交xxxx欧美 | 国内揄拍国内精品人妻 | 亚洲爆乳精品无码一区二区三区 | 帮老师解开蕾丝奶罩吸乳网站 | 亚洲欧美日韩国产精品一区二区 | 乱码av麻豆丝袜熟女系列 | 色一情一乱一伦一区二区三欧美 | 日本高清一区免费中文视频 | 久久精品无码一区二区三区 | 国产成人精品三级麻豆 | 亚洲日韩精品欧美一区二区 | 色婷婷欧美在线播放内射 | 亚洲日韩一区二区三区 | 亚洲色欲久久久综合网东京热 | 无码人妻少妇伦在线电影 | 97久久国产亚洲精品超碰热 | 国产口爆吞精在线视频 | 少妇性l交大片 | 一区二区三区乱码在线 | 欧洲 | 成人性做爰aaa片免费看 | 精品无人区无码乱码毛片国产 | 波多野42部无码喷潮在线 | 欧美丰满熟妇xxxx性ppx人交 | 亚洲综合无码久久精品综合 | 131美女爱做视频 | 六月丁香婷婷色狠狠久久 | 亚洲乱亚洲乱妇50p | 精品无人区无码乱码毛片国产 | 日本www一道久久久免费榴莲 | 欧美成人免费全部网站 | 国内精品人妻无码久久久影院 | 亚洲色偷偷偷综合网 | 波多野结衣av在线观看 | 全黄性性激高免费视频 | 久久午夜无码鲁丝片秋霞 | 青青久在线视频免费观看 | 一本色道久久综合狠狠躁 | 国内精品人妻无码久久久影院 | 漂亮人妻洗澡被公强 日日躁 | 丝袜美腿亚洲一区二区 | 2019nv天堂香蕉在线观看 | 欧美一区二区三区视频在线观看 | 欧美精品一区二区精品久久 | 无码人妻出轨黑人中文字幕 | 欧美野外疯狂做受xxxx高潮 | 乱码av麻豆丝袜熟女系列 | 国内精品人妻无码久久久影院 | 国产精品久久久久无码av色戒 | 欧美激情综合亚洲一二区 | 国产做国产爱免费视频 | 300部国产真实乱 | 熟女俱乐部五十路六十路av | 久久人人爽人人爽人人片av高清 | 国产电影无码午夜在线播放 | 99久久人妻精品免费二区 | 国产成人精品久久亚洲高清不卡 | 一区二区三区乱码在线 | 欧洲 | 在线成人www免费观看视频 | 在线 国产 欧美 亚洲 天堂 | 欧美 亚洲 国产 另类 | 亚洲а∨天堂久久精品2021 | 俺去俺来也在线www色官网 | 天天拍夜夜添久久精品大 | 免费播放一区二区三区 | 国产乱人无码伦av在线a | 性生交片免费无码看人 | 天天拍夜夜添久久精品 | 欧洲欧美人成视频在线 | 99久久久无码国产aaa精品 | 亚洲色大成网站www | 青草青草久热国产精品 | 女高中生第一次破苞av | 色一情一乱一伦 | 国产人妻大战黑人第1集 | 强开小婷嫩苞又嫩又紧视频 | 亚洲娇小与黑人巨大交 | 久久这里只有精品视频9 | 一本久道高清无码视频 | 欧美zoozzooz性欧美 | 久久精品中文字幕一区 | 欧美丰满熟妇xxxx性ppx人交 | 成熟女人特级毛片www免费 | 成人无码视频在线观看网站 | 精品水蜜桃久久久久久久 | 欧美野外疯狂做受xxxx高潮 | 精品欧洲av无码一区二区三区 | 精品乱子伦一区二区三区 | 天天躁夜夜躁狠狠是什么心态 | 国产精品久久久久无码av色戒 | 亚洲精品一区三区三区在线观看 | 日韩在线不卡免费视频一区 | 亚洲国产精品毛片av不卡在线 | 国产 浪潮av性色四虎 | 丝袜足控一区二区三区 | 日本大香伊一区二区三区 | 综合激情五月综合激情五月激情1 | 久久精品99久久香蕉国产色戒 | 日本精品人妻无码免费大全 | а√资源新版在线天堂 | 亚洲区欧美区综合区自拍区 | 四虎永久在线精品免费网址 | 一区二区三区乱码在线 | 欧洲 | 国产av无码专区亚洲awww | 亚洲欧美色中文字幕在线 | 亚洲国产精品毛片av不卡在线 | 国产在热线精品视频 | 思思久久99热只有频精品66 | 久久精品女人的天堂av | 人妻与老人中文字幕 | 大色综合色综合网站 | 成人精品天堂一区二区三区 | 国产麻豆精品一区二区三区v视界 | 色狠狠av一区二区三区 | 无码任你躁久久久久久久 | 日韩欧美中文字幕在线三区 | 中文字幕无码av激情不卡 | 成人三级无码视频在线观看 | 岛国片人妻三上悠亚 | 夜精品a片一区二区三区无码白浆 | 99久久精品无码一区二区毛片 | 国产在线精品一区二区三区直播 | 亚洲国产精品美女久久久久 | 乱人伦人妻中文字幕无码久久网 | 丝袜足控一区二区三区 | 亚洲一区二区三区香蕉 | 国产精品对白交换视频 | 露脸叫床粗话东北少妇 | 18精品久久久无码午夜福利 | 日本一卡二卡不卡视频查询 | 一本久久伊人热热精品中文字幕 | 特黄特色大片免费播放器图片 | 国产精品久久久av久久久 | 欧美日韩精品 | 性色欲情网站iwww九文堂 | 久久99久久99精品中文字幕 | 日韩精品久久久肉伦网站 | 性生交片免费无码看人 | 亚洲伊人久久精品影院 | 国产精品第一国产精品 | 久久综合狠狠综合久久综合88 | 亚洲精品国产精品乱码不卡 | av无码久久久久不卡免费网站 | 精品国产成人一区二区三区 | 国内精品九九久久久精品 | 日本精品人妻无码免费大全 | 国产精品福利视频导航 | 亚洲熟妇色xxxxx欧美老妇 | yw尤物av无码国产在线观看 | 国产午夜亚洲精品不卡下载 | 欧美国产日产一区二区 | 99久久精品国产一区二区蜜芽 | 天天摸天天透天天添 | 国产sm调教视频在线观看 | 国产亚洲精品久久久ai换 | 美女扒开屁股让男人桶 | 日本熟妇乱子伦xxxx | 国产亚洲日韩欧美另类第八页 | 99久久精品日本一区二区免费 | 国产艳妇av在线观看果冻传媒 | 人妻少妇被猛烈进入中文字幕 | 正在播放老肥熟妇露脸 | 中文无码精品a∨在线观看不卡 | 久久午夜无码鲁丝片午夜精品 | 丰满人妻一区二区三区免费视频 | 天天拍夜夜添久久精品大 | 俺去俺来也在线www色官网 | 日本大香伊一区二区三区 | 国产在线一区二区三区四区五区 | 亚洲欧美日韩成人高清在线一区 | 亚洲综合无码一区二区三区 | 国产成人精品视频ⅴa片软件竹菊 | 中文字幕无码免费久久99 | 国产深夜福利视频在线 | 久久久精品人妻久久影视 | 欧美激情内射喷水高潮 | 无码人妻出轨黑人中文字幕 | 99国产精品白浆在线观看免费 | 超碰97人人做人人爱少妇 | 欧美人与动性行为视频 | 国产精品人人爽人人做我的可爱 | 人妻体内射精一区二区三四 | 亚洲国产精品无码久久久久高潮 | 男女爱爱好爽视频免费看 | 亚洲一区二区三区国产精华液 | 久久熟妇人妻午夜寂寞影院 | 扒开双腿吃奶呻吟做受视频 | 性欧美疯狂xxxxbbbb | 荫蒂添的好舒服视频囗交 | 亚洲乱码国产乱码精品精 | 亚洲色偷偷男人的天堂 | 亚洲精品国产第一综合99久久 | 久久亚洲中文字幕无码 | 国产亚洲人成在线播放 | 国产偷抇久久精品a片69 | 男人扒开女人内裤强吻桶进去 | 一本色道婷婷久久欧美 | а√天堂www在线天堂小说 | 国产成人人人97超碰超爽8 | 99精品久久毛片a片 | 强奷人妻日本中文字幕 | 麻豆精品国产精华精华液好用吗 | 丰满人妻一区二区三区免费视频 | 久久亚洲精品中文字幕无男同 | 日韩成人一区二区三区在线观看 | 久久午夜夜伦鲁鲁片无码免费 | 国产精品资源一区二区 | 亚洲乱亚洲乱妇50p | 好男人社区资源 | 国产人妖乱国产精品人妖 | 色狠狠av一区二区三区 | 最新国产麻豆aⅴ精品无码 | 色一情一乱一伦 | 亚洲成a人片在线观看无码 | 无码av中文字幕免费放 | 国内少妇偷人精品视频免费 | 牲交欧美兽交欧美 | 成熟人妻av无码专区 | 日本在线高清不卡免费播放 | 午夜熟女插插xx免费视频 | 7777奇米四色成人眼影 | 亚洲中文字幕在线无码一区二区 | 亚洲欧洲日本无在线码 | 乱人伦中文视频在线观看 | 搡女人真爽免费视频大全 | 男人扒开女人内裤强吻桶进去 | 扒开双腿疯狂进出爽爽爽视频 | 亚洲精品成a人在线观看 | 国产精品无码一区二区桃花视频 | 国产精品va在线播放 | 中文字幕色婷婷在线视频 | 熟女少妇在线视频播放 | 午夜精品一区二区三区在线观看 | 国产午夜亚洲精品不卡下载 | 日韩亚洲欧美精品综合 | 自拍偷自拍亚洲精品10p | 国精产品一品二品国精品69xx | 精品午夜福利在线观看 | 国产精品高潮呻吟av久久 | 牲欲强的熟妇农村老妇女 | 一本色道久久综合狠狠躁 | 国色天香社区在线视频 | 小泽玛莉亚一区二区视频在线 | 狠狠色色综合网站 | 国产精品理论片在线观看 | 帮老师解开蕾丝奶罩吸乳网站 | 亚洲男人av天堂午夜在 | 性史性农村dvd毛片 | 国产熟妇高潮叫床视频播放 | 在线播放免费人成毛片乱码 | 国产精品亚洲综合色区韩国 | 久久无码中文字幕免费影院蜜桃 | 人妻少妇精品视频专区 | 国产办公室秘书无码精品99 | 老子影院午夜精品无码 | 亚洲 a v无 码免 费 成 人 a v | 亚洲经典千人经典日产 | 日日麻批免费40分钟无码 | 内射后入在线观看一区 | 成人av无码一区二区三区 | 精品无码av一区二区三区 | 久久伊人色av天堂九九小黄鸭 | 国产99久久精品一区二区 | 一本久道久久综合婷婷五月 | 精品夜夜澡人妻无码av蜜桃 | 国产成人无码午夜视频在线观看 | 成人一区二区免费视频 | 狂野欧美激情性xxxx | 1000部啪啪未满十八勿入下载 | 亚洲中文字幕无码一久久区 | 曰韩少妇内射免费播放 | 亚洲成a人片在线观看日本 | 人妻夜夜爽天天爽三区 | 国产精品亚洲一区二区三区喷水 | 荫蒂添的好舒服视频囗交 | 色综合久久久久综合一本到桃花网 | 装睡被陌生人摸出水好爽 | 国产乱人伦偷精品视频 | 国产亚洲精品久久久久久久久动漫 | 99re在线播放 | 亚洲人成无码网www | 欧美日本精品一区二区三区 | 精品久久久久久人妻无码中文字幕 | 中文字幕日产无线码一区 | 亚洲の无码国产の无码步美 | 伦伦影院午夜理论片 | 麻豆国产人妻欲求不满谁演的 | 少妇高潮喷潮久久久影院 | 久久熟妇人妻午夜寂寞影院 | 国精产品一品二品国精品69xx | 成人无码影片精品久久久 | 久久视频在线观看精品 | 九九久久精品国产免费看小说 | 人人妻人人澡人人爽人人精品 | 欧美精品国产综合久久 | 人妻人人添人妻人人爱 | 波多野结衣av一区二区全免费观看 | 麻豆md0077饥渴少妇 | 午夜无码人妻av大片色欲 | 99久久精品国产一区二区蜜芽 | 无码中文字幕色专区 | 狠狠色噜噜狠狠狠狠7777米奇 | 国产精品怡红院永久免费 | 久久久久人妻一区精品色欧美 | 久久综合给合久久狠狠狠97色 | 亚洲午夜无码久久 | yw尤物av无码国产在线观看 | 久久视频在线观看精品 | 一本色道久久综合亚洲精品不卡 | 久久久精品456亚洲影院 | 97久久国产亚洲精品超碰热 | 久久午夜夜伦鲁鲁片无码免费 | 亚洲熟妇色xxxxx欧美老妇y | 在线播放免费人成毛片乱码 | 无码中文字幕色专区 | 国产色xx群视频射精 | 日日天干夜夜狠狠爱 | 久久久久久久久蜜桃 | 麻豆成人精品国产免费 | 99久久精品日本一区二区免费 | 又黄又爽又色的视频 | 亚洲s码欧洲m码国产av | 无码人妻少妇伦在线电影 | 少妇性l交大片欧洲热妇乱xxx | 久久99精品国产麻豆蜜芽 | 鲁鲁鲁爽爽爽在线视频观看 | 日日天干夜夜狠狠爱 | 亚洲va中文字幕无码久久不卡 | 国产区女主播在线观看 | 老子影院午夜伦不卡 | 日本一本二本三区免费 | 国产成人一区二区三区别 | 久久久成人毛片无码 | 无码av免费一区二区三区试看 | 白嫩日本少妇做爰 | 久久国语露脸国产精品电影 | 动漫av一区二区在线观看 | 午夜成人1000部免费视频 | 妺妺窝人体色www婷婷 | 97精品国产97久久久久久免费 | 人人超人人超碰超国产 | 熟妇人妻中文av无码 | 久久久久成人精品免费播放动漫 | 麻豆蜜桃av蜜臀av色欲av | 两性色午夜免费视频 | 动漫av网站免费观看 | 精品无人国产偷自产在线 | 国产成人精品无码播放 | 亚洲精品久久久久久久久久久 | 无码成人精品区在线观看 | 狠狠亚洲超碰狼人久久 | 国产成人无码av片在线观看不卡 | av无码不卡在线观看免费 | 国产美女极度色诱视频www | 欧美自拍另类欧美综合图片区 | 久久综合狠狠综合久久综合88 | 国产精品久久久久7777 | 狠狠综合久久久久综合网 | 国产深夜福利视频在线 | 国产精品久久久久无码av色戒 | 性欧美牲交xxxxx视频 | 日本一区二区三区免费播放 | 99re在线播放 | 乱人伦人妻中文字幕无码 | 亚无码乱人伦一区二区 | 中文字幕乱妇无码av在线 | 国产午夜视频在线观看 | 亚洲成色在线综合网站 | 国产成人无码av在线影院 | 亚洲熟熟妇xxxx | 无码免费一区二区三区 | 性欧美熟妇videofreesex | 久久99精品国产麻豆蜜芽 | 中文字幕无码乱人伦 | 国语自产偷拍精品视频偷 | 国产成人一区二区三区别 | 成人欧美一区二区三区黑人 | 青青草原综合久久大伊人精品 | 久久zyz资源站无码中文动漫 | 国产三级久久久精品麻豆三级 | 大地资源网第二页免费观看 | 美女黄网站人色视频免费国产 | 免费中文字幕日韩欧美 | 3d动漫精品啪啪一区二区中 | 亚洲а∨天堂久久精品2021 | 国产综合久久久久鬼色 | 国产精品久久久久久亚洲毛片 | 成在人线av无码免观看麻豆 | 激情综合激情五月俺也去 | 国产精品va在线观看无码 | 99视频精品全部免费免费观看 | 国产成人无码午夜视频在线观看 | 亚洲成熟女人毛毛耸耸多 | 人人妻人人澡人人爽精品欧美 | 亚洲欧美色中文字幕在线 | 色狠狠av一区二区三区 | 少妇性l交大片欧洲热妇乱xxx | 精品国产一区二区三区av 性色 | 日本精品久久久久中文字幕 | 日韩少妇内射免费播放 | 亚洲国产av美女网站 | 国产超级va在线观看视频 | 无码人妻丰满熟妇区五十路百度 | 成人无码视频免费播放 | 综合人妻久久一区二区精品 | 久久97精品久久久久久久不卡 | 欧美xxxx黑人又粗又长 | 国产成人一区二区三区别 | 午夜性刺激在线视频免费 | 国产av久久久久精东av | 欧美大屁股xxxxhd黑色 | 中文字幕日产无线码一区 | 国产乡下妇女做爰 | 欧美老妇交乱视频在线观看 | 中文字幕人妻无码一区二区三区 |