<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>

          免費(fèi)贈(zèng)書 | 日數(shù)據(jù)量過億的大規(guī)模爬蟲是怎么實(shí)現(xiàn)的?

          共 6241字,需瀏覽 13分鐘

           ·

          2020-12-04 20:51

          劃重點(diǎn):請(qǐng)大家買好瓜子、搬好凳子坐下學(xué)習(xí),并準(zhǔn)備好爭(zhēng)奪文末贈(zèng)送的獎(jiǎng)品!


          我們身邊接觸最頻繁、同時(shí)也是最大的爬蟲莫過于幾大搜索引擎。但是搜索引擎的爬取方式和我們爬蟲工程師接觸的方式差異比較大,沒有太大的參考價(jià)值,我們今天要講的是輿情方向的爬蟲(架構(gòu)以及關(guān)鍵技術(shù)原理),主要涉及:


          1. 網(wǎng)頁文本智能提取;

          2. 分布式爬蟲;

          3. 爬蟲 DATA/URL 去重;

          4. 爬蟲部署;

          5. 分布式爬蟲調(diào)度;

          6. 自動(dòng)化渲染技術(shù);

          7. 消息隊(duì)列在爬蟲領(lǐng)域的應(yīng)用;

          8. 各種各樣形式的反爬蟲;

          一、網(wǎng)頁文本智能提取


          輿情其實(shí)就是輿論情況,要掌握輿情,那么就必須掌握足夠多的內(nèi)容資訊。除了一些開放了商業(yè)接口的大型內(nèi)容/社交類平臺(tái)(例如微博)之外,其他都需要依靠爬蟲去采集。因此,輿情方向的爬蟲工程師需要面對(duì)的是千千萬萬個(gè)內(nèi)容和結(jié)構(gòu)都不同的站點(diǎn)。我們用一個(gè)圖來表示他們面對(duì)的問題:

          沒錯(cuò),他們的采集器必須要能夠適配千千萬萬個(gè)站點(diǎn)的結(jié)構(gòu),從風(fēng)格迥異的 HTML 文本中提取出主體內(nèi)容——標(biāo)題、正文、發(fā)布時(shí)間和作者。


          如果是你,你會(huì)用什么樣的設(shè)計(jì)來滿足業(yè)務(wù)需求呢?


          曾經(jīng)我也設(shè)想過這樣的問題,在技術(shù)群里也看到有群友提出類似的問題,但是很難得到滿意的答案。有的人說:


          1. 用歸類法,相似的內(nèi)容歸類到一起,然后給一類內(nèi)容配置提取規(guī)則;

          2. 用正則,提取指定標(biāo)簽中的內(nèi)容;

          3. 用深度學(xué)習(xí),NLP 語義分析出哪里是有意義的內(nèi)容,提取出來;

          4. 用計(jì)算機(jī)視覺,讓人去點(diǎn)擊,然后按照頁面相似度分類提取(其實(shí)就是歸類法的自動(dòng)化版本);

          5. 用算法,計(jì)算出文本的密度,然后提??;


          總之各種各樣的想法層出不窮,但是最后都沒有聽到實(shí)際應(yīng)用的消息。目前來說,大部分公司使用的都是人工配置 XPATH 規(guī)則的方式,采集的時(shí)候通過網(wǎng)址來匹配對(duì)應(yīng)的提取規(guī)則,然后調(diào)用規(guī)則來實(shí)現(xiàn)多站點(diǎn)的爬取。這種方法很有效,而且在企業(yè)中應(yīng)用已久,比較穩(wěn)定,但缺點(diǎn)也顯而易見——費(fèi)時(shí)間、費(fèi)人工、費(fèi)錢!


          偶有一天,我在微信技術(shù)群里看到有人(優(yōu)秀的 Python 工程師青南)發(fā)表了一個(gè)用于自動(dòng)化提取文本的算法庫,GeneralNewsExtractor[1]?(以下簡(jiǎn)稱 GNE)。這個(gè)庫參考了武漢郵電科學(xué)研究院洪鴻輝、丁世濤、黃傲、郭致遠(yuǎn)等人編寫的論文——《基于文本及符號(hào)密度的網(wǎng)頁正文提取方法》,并在論文的基礎(chǔ)上用 Python 代碼進(jìn)行了具體實(shí)現(xiàn),也就是 GNE。它的原理是通過提取網(wǎng)頁 DOM 中的文本以及其中的標(biāo)點(diǎn)符號(hào),以文本中標(biāo)點(diǎn)符號(hào)的密度作為基礎(chǔ),使用算法從一句話延伸到一段文字和一篇文章。



          GNE 能夠有效排除正文以外的的廣告、推薦欄、介紹欄等“噪聲”內(nèi)容,準(zhǔn)確識(shí)別出網(wǎng)頁正文,且識(shí)別率高達(dá) 99%(測(cè)試選用的內(nèi)容為國(guó)內(nèi)主流門戶/媒體平臺(tái)中的文章)。


          GNE 的具體算法細(xì)節(jié)以及源碼解析請(qǐng)翻閱《Python3 網(wǎng)絡(luò)爬蟲寶典》第 5 章。


          有了它,基本上就可以解決 90% 以上的輿情方向爬蟲解析的需求,剩下的 10% 可以基于提取規(guī)則進(jìn)行針對(duì)性調(diào)整或者完全定制化開發(fā),解放了一大波 XPATH 工程師。


          二、爬蟲 DATA/URL 去重


          輿情業(yè)務(wù)必須緊盯網(wǎng)站是否有新的內(nèi)容發(fā)布,要求是越快越好,但由于各項(xiàng)軟硬件限制,通常會(huì)要求在 30 分鐘內(nèi)或者 15 分鐘內(nèi)監(jiān)聽到新內(nèi)容。要實(shí)現(xiàn)對(duì)目標(biāo)網(wǎng)站內(nèi)容變化的監(jiān)聽,那么我們可以選擇的比較好的方式就是輪詢。不停地訪問網(wǎng)頁,并且判斷是否有“新內(nèi)容”出現(xiàn),如果有的話就執(zhí)行爬取,沒有“新內(nèi)容”就不爬取。


          那么問題來了,應(yīng)用程序如何知道哪些內(nèi)容是“新的”、哪些內(nèi)容又是“舊的”的呢?


          問題拆解一下,“新內(nèi)容”就是沒有爬過的內(nèi)容。這時(shí)候我們需要用一個(gè)東西來記錄這篇文章是否被爬取過,每次有要爬取的文章時(shí)就比對(duì)一下,這就是解決這個(gè)問題的辦法。


          那又依靠什么來進(jìn)行比對(duì)呢?


          我們都知道文章的 URL 幾乎都是不變且不會(huì)重復(fù)的,因此可以選擇文章的 URL 作為判定的依據(jù),也就是把爬取過的 URL 放到一個(gè)類似列表一樣的容器里存儲(chǔ)起來,每次有待爬取的 URL 就判斷它是否已經(jīng)被存在容器里,如果在就說明已經(jīng)爬過了,直接丟棄,進(jìn)入下一個(gè) URL 的判斷流程。整體邏輯就像下面這張圖一樣:



          這就是爬蟲領(lǐng)域的“去重”。實(shí)際上去重可以粗略的分為內(nèi)容(DATA)去重和鏈接(URL)去重,這里我們講的只是輿情方向的去重需求,如果是電商方向的去重,那么就不能用 URL 作為判斷依據(jù),因?yàn)殡娚膛老x(例如比價(jià)軟件)的目的主要是判斷價(jià)格的變化,這時(shí)候判斷變化的依據(jù)應(yīng)該是商品的關(guān)鍵信息(例如價(jià)格、折扣),也就是 DATA 去重。


          去重的原理明白了,那用什么東西作為存放去重依據(jù)的容器呢?MySQL?Redis?MongoDB??jī)?nèi)存?實(shí)際上大部分工程師都選擇 Redis 作為存放去重依據(jù)的容器,但實(shí)際上 MySQL、MongoDB 和內(nèi)存都是可以充當(dāng)容器的,至于為什么會(huì)選擇 Redis,它又比其他數(shù)據(jù)存儲(chǔ)好在哪里?你可以翻閱《Python3 網(wǎng)絡(luò)爬蟲寶典》的第 3 章。


          三、分布式爬蟲


          無論是輿情方向的爬蟲還是電商方向的爬蟲,要承擔(dān)的爬取量都是非常大的。少則每日百萬數(shù)據(jù),多則每日數(shù)十億數(shù)據(jù)。以往大家了解的單機(jī)爬蟲,在性能和資源方面都無法滿足需求。既然 1 個(gè)滿足不了,那就 10 個(gè)、100 個(gè)!這就是分布式爬蟲出現(xiàn)的背景。


          眾所周知,分布式和單機(jī)要面對(duì)的問題是有差異的,除了業(yè)務(wù)目標(biāo)是相同的之外,分布式還要考慮多個(gè)個(gè)體之間的協(xié)作,尤其是資源的共享和競(jìng)爭(zhēng)。

          在只有 1 個(gè)爬蟲應(yīng)用的時(shí)候,也只有它 1 個(gè)讀取待爬隊(duì)列、只有 1 個(gè)存儲(chǔ)數(shù)據(jù)、只有它 1 個(gè)判斷 URL 是否重復(fù)。但有幾十幾百個(gè)爬蟲應(yīng)用的時(shí)候,就需要區(qū)分先后順序,避免出現(xiàn)多個(gè)爬蟲應(yīng)用訪問同一個(gè) URL 的情況(因?yàn)檫@不僅浪費(fèi)時(shí)間,還浪費(fèi)資源)。而且,只有 1 個(gè)爬蟲應(yīng)用的時(shí)候只需要把它放在 1 臺(tái)計(jì)算機(jī)(服務(wù)器)上運(yùn)行就可以了,但是爬蟲應(yīng)用突然變得這么多,又應(yīng)該如何部署到不同的計(jì)算機(jī)上呢?手動(dòng)一個(gè)個(gè)上傳,然后一個(gè)個(gè)啟動(dòng)嗎?


          資源問題


          先說資源共享和競(jìng)爭(zhēng)的情況,為了解決 URL 待爬隊(duì)列和已經(jīng)爬隊(duì)列的共享,那么必須將隊(duì)列(也就是上面提到的存放 URL 的容器)放到一個(gè)可以公開(多個(gè)爬蟲應(yīng)用)訪問的地方,例如部署在服務(wù)器上的 Redis。


          這時(shí)候又出現(xiàn)一個(gè)新狀況,隨著數(shù)據(jù)量越來越大,要存儲(chǔ)的 URL 越來越多,后面很有可能出現(xiàn)因?yàn)榇鎯?chǔ)空間需求過大而導(dǎo)致成本遞增的問題。因?yàn)?Redis 是利用內(nèi)存來存儲(chǔ)數(shù)據(jù)的,所以存放的 URL 越多就需要越多的內(nèi)存,而內(nèi)存又是硬件設(shè)備里價(jià)格相對(duì)較高的硬件,所以不得不考慮這個(gè)問題。


          好在一個(gè)叫做布隆的人發(fā)明了一種算法——Bloom Filter(布隆過濾器),這種算法通過哈希映射的方式來標(biāo)記一個(gè)對(duì)象(這里是 URL)是否存在,這樣可以將內(nèi)存的占用率大大降低,按 1 億條長(zhǎng)度為 32 字符的 URL MD5 值來計(jì)算,使用 Bloom Filter 前后的差距大約在 30倍。關(guān)于 Bloom Filter 的算法原理和代碼實(shí)現(xiàn)解讀可翻閱《Python3 網(wǎng)絡(luò)爬蟲寶典》第 3 章 。


          部署問題


          一個(gè)個(gè)文件上傳,一次次手動(dòng)運(yùn)行爬蟲實(shí)在是太累了。你可以向運(yùn)維同事尋求技術(shù)支持,但也可以自己探尋這些能夠減輕你工作量的自動(dòng)化部署方式。目前業(yè)內(nèi)知名的持續(xù)集成和部署莫過于 GitLab 的 GitLab Runner 和 GitHub Action,又或者是借助 K8S 的容器化來實(shí)現(xiàn)。但它們只能幫助你實(shí)現(xiàn)部署和啟動(dòng),而爬蟲應(yīng)用的一些管理功能就指望不上了。遂,今天要給大家介紹的是另一種實(shí)現(xiàn)方式——使用 Crawlab。


          Crawlab 是一款由知名外企工程師開發(fā)的分布式爬蟲管理平臺(tái),它不僅支持 Python 語言編寫的爬蟲,幾乎可以兼容大部分編程語言和應(yīng)用程序。借助 Crawlab,我們可以將爬蟲應(yīng)用分散到不同的計(jì)算機(jī)(服務(wù)器)上,而且能夠在可視化界面設(shè)定定時(shí)任務(wù)、查看平臺(tái)上爬蟲應(yīng)用的狀態(tài)以及環(huán)境依賴等信息。具體如下圖所示:


          面對(duì)一款如此實(shí)用的平臺(tái)工具,作為工程師的我們不禁想問:


          1. 它是如何把文件分散到不同計(jì)算機(jī)的?

          2. 它如何實(shí)現(xiàn)不同計(jì)算機(jī)(多節(jié)點(diǎn))之間通信的?

          3. 它是如何實(shí)現(xiàn)多語言兼容的?

          4. .……


          其中我們比較關(guān)注的多節(jié)點(diǎn)通信是借助 Redis 實(shí)現(xiàn)的,文件分散同步是借助 MongoDB 實(shí)現(xiàn)的。更多細(xì)節(jié)可翻閱《Python3 網(wǎng)絡(luò)爬蟲寶典》 第 6 章。


          除了這樣的平臺(tái)之外,Python 爬蟲工程師常常接觸的莫過于 Scrapy 框架以及相關(guān)衍生的庫。Scrapy 團(tuán)隊(duì)官方開發(fā)了一個(gè)名為 Scrapyd 的庫,它專門用來部署 Scrapy 框架開發(fā)的爬蟲應(yīng)用。在部署 Scrapy 應(yīng)用時(shí),我們通常只需要執(zhí)行 1 行命令就可以把爬蟲程序部署到服務(wù)器上。你想不想知道背后的邏輯:


          1. 程序以什么樣的形式上傳到服務(wù)器的?

          2. 程序在服務(wù)器上如何運(yùn)行的?

          3. 為什么可以查看到每個(gè)任務(wù)運(yùn)行的開始時(shí)間和結(jié)束時(shí)間?

          4. 中途取消任務(wù)執(zhí)行的功能是怎么實(shí)現(xiàn)的?

          5. 它的版本控制是怎么實(shí)現(xiàn)的?

          6. 如果不是 Scrapy 框架編寫的 Python 應(yīng)用,能實(shí)現(xiàn)像上面幾點(diǎn)那樣的監(jiān)控和操作嗎?


          實(shí)際上 Scrapy 應(yīng)用會(huì)被打包成為一個(gè)后綴為“.egg” 的壓縮包,以 HTTP 的形式上傳到服務(wù)器上。當(dāng)服務(wù)端程序需要執(zhí)行這個(gè)程序時(shí),先將它復(fù)制到操作系統(tǒng)的臨時(shí)文件夾,執(zhí)行時(shí)將其導(dǎo)入到當(dāng)前 Python 環(huán)境,執(zhí)行完畢后刪除該文件。至于它的執(zhí)行時(shí)間和中斷操作,實(shí)際上借助了 Python 進(jìn)程接口,具體細(xì)節(jié)翻閱《Python3 網(wǎng)絡(luò)爬蟲寶典》 第 6 章。


          四、自動(dòng)化渲染技術(shù)


          為了實(shí)現(xiàn)炫酷的效果,或者說為了節(jié)省靜態(tài)資源對(duì)帶寬的占用,很多網(wǎng)站都是借助 JavaScript 來實(shí)現(xiàn)對(duì)頁面內(nèi)容的優(yōu)化。Python 程序本身是無法解釋 JavaScript 和 HTML 代碼的,因此無法獲得我們?cè)跒g覽器中“看到”,但實(shí)際上并不是“真實(shí)存在”的內(nèi)容,因?yàn)檫@些內(nèi)容都是由瀏覽器渲染出來的,只存在于瀏覽器中,HTML 文檔里面還是那些文本、JavaScript 文件中還是那些代碼,圖片、視頻和那些特效并不會(huì)出現(xiàn)在代碼中,我們看到的一切都是瀏覽器的功勞。


          由于 Python 也無法獲取瀏覽器渲染后的內(nèi)容,所以當(dāng)我們像往常一樣寫代碼爬取上面的數(shù)據(jù)時(shí),就會(huì)發(fā)現(xiàn)拿到的數(shù)據(jù)和看到的并不一樣,任務(wù)它就失敗了。

          這時(shí)候我們就需要用到自動(dòng)化渲染技術(shù)了,實(shí)際上像 Chrome 和 FireFox 這樣的瀏覽器都開放了接口,允許其他編程語言按照協(xié)議規(guī)范操控瀏覽器?;谶@樣的技術(shù)背景,有團(tuán)隊(duì)開發(fā)出了像 Selenium 和 Puppeteer 這樣的工具,然后我們就可以用 Python (其他語言也可以)代碼來操作瀏覽器了。讓瀏覽器幫助我們做一些用戶名密碼輸入、登錄按鈕點(diǎn)擊、文本和圖片渲染、驗(yàn)證碼滑動(dòng)等操作,從而打破 Python 與瀏覽器本身的差異壁壘,借助瀏覽器渲染內(nèi)容后再返回給 Python 程序,然后拿到和我們?cè)诰W(wǎng)頁上看到的一樣的內(nèi)容。


          除了瀏覽器,APP 也有類似的情況。具體操作實(shí)踐和案例細(xì)節(jié)可翻閱《Python3 網(wǎng)絡(luò)爬蟲寶典》 第 2 章。


          五、消息隊(duì)列在爬蟲領(lǐng)域的應(yīng)用


          之前的描述中,我們并沒有提到爬取時(shí)候的細(xì)節(jié)。假設(shè)這樣一個(gè)正常的爬蟲場(chǎng)景:爬蟲先訪問網(wǎng)站的文章列表頁,然后根據(jù)列表頁的 URL 進(jìn)入詳情頁進(jìn)行爬取。這里要注意,文章詳情頁的數(shù)量一定是比列表頁的數(shù)量多 N 倍的,如果列表展示的是 20 條內(nèi)容,那么就是多 20 倍。


          如果我們需要爬取的網(wǎng)站很多,那么就會(huì)用到分布式爬蟲。如果分布式爬蟲只是把 1 個(gè)爬蟲程序復(fù)制出 N 份來運(yùn)行,那么就會(huì)出現(xiàn)資源分配不均衡的情況,因?yàn)樵谏厦嫣岬降倪@種情況下,每 1 個(gè)爬蟲都需要這么干活。實(shí)際上我們可以有更好的搭配方式,讓它們的資源得到最大利用。例從列表頁到詳情頁可以抽象為生產(chǎn)者和消費(fèi)者模型:



          4 號(hào)和 5 號(hào)爬蟲應(yīng)用只負(fù)責(zé)將列表頁中抽取詳情頁的 URL,然后推送到一個(gè)隊(duì)列中,另外幾個(gè)爬蟲程序從隊(duì)列中取出詳情頁的 URL 進(jìn)行爬取。當(dāng)列表頁和詳情頁數(shù)量差距比較大的時(shí)候,我們可以增加右側(cè)的爬蟲程序數(shù)量,差距較小的時(shí)候就減少右側(cè)的爬蟲程序(或者增加左側(cè)的爬蟲程序,具體視情況定)。


          左側(cè)的爬蟲程序相對(duì)于隊(duì)列這條“數(shù)據(jù)采集生產(chǎn)線”來說,它就是生產(chǎn)者,右側(cè)爬蟲程序的就是消費(fèi)者。有了這樣的結(jié)構(gòu),我們就可以根據(jù)實(shí)際情況對(duì)生產(chǎn)者或者消費(fèi)者的熟練進(jìn)行調(diào)整,實(shí)現(xiàn)資源的最大化利用。另外一個(gè)好處是當(dāng)生產(chǎn)者拿到的 URL 越來越多,但消費(fèi)者一時(shí)消費(fèi)不過來時(shí),URL 會(huì)一直存放在隊(duì)列中,等消費(fèi)能力上升時(shí)就能夠再次實(shí)現(xiàn)均衡。有了這樣的生產(chǎn)線,我們就不用擔(dān)心一下突然涌來很多的 URL 或者一下突然把隊(duì)列的 URL 消費(fèi)一空,隊(duì)列這種削峰填谷的能力除了在后端應(yīng)用中大放異彩之外,在爬蟲應(yīng)用中也發(fā)揮了很大的作用。


          關(guān)于爬蟲(以及分布式爬蟲)程序接入消息隊(duì)列的具體實(shí)現(xiàn)和細(xì)節(jié)可翻閱《Python3 網(wǎng)絡(luò)爬蟲寶典》 第 4 章。


          六、各種各樣形式的反爬蟲


          你想要我偏不給!


          網(wǎng)站可不會(huì)輕易讓你爬取站點(diǎn)上面的內(nèi)容,它們往往會(huì)從網(wǎng)絡(luò)協(xié)議、瀏覽器特征、編程語言差異、人機(jī)差異等方面給爬蟲工程師設(shè)置障礙,常見的有滑塊驗(yàn)證碼、拼圖驗(yàn)證碼、封 IP、檢查 COOKIE、要求登錄、設(shè)定復(fù)雜的加密邏輯、混淆前端代碼等。


          水來土掩、兵來將擋!爬蟲工程師與目標(biāo)網(wǎng)站的工程師你來我往的過招就像兵家爾虞我詐一般精彩?!禤ython3 反爬蟲原理與繞過實(shí)戰(zhàn)》一書囊括了市面上 80% 以上的反爬蟲手段和爬蟲技巧,詳細(xì)解讀雙方所用招術(shù),使各位看客從中學(xué)到不少使用招式。具體細(xì)節(jié)可翻閱該書,領(lǐng)略技術(shù)領(lǐng)域的江湖!


          小 結(jié)


          今天我們一起學(xué)習(xí)了日數(shù)據(jù)量過億的大規(guī)模爬蟲實(shí)踐路上的關(guān)鍵技術(shù)點(diǎn),包括文本智能提取、分布式爬蟲、爬蟲部署和調(diào)度、去重、自動(dòng)化渲染等。學(xué)會(huì)了這些技術(shù)并融會(huì)貫通,那么實(shí)現(xiàn)日數(shù)據(jù)過億的爬蟲就不是問題了。


          這些經(jīng)驗(yàn)都來自一線爬蟲工程師,同時(shí)這些技術(shù)和設(shè)計(jì)都經(jīng)過了長(zhǎng)期的工作驗(yàn)證,能夠直接應(yīng)用在工作當(dāng)中。


          活? 動(dòng)


          上面多次提到了《Python3 網(wǎng)絡(luò)爬蟲寶典》,小編購(gòu)買了幾本書用來感謝大家對(duì)小編的支持。想要書的朋友請(qǐng)?jiān)谠u(píng)論區(qū)留言,說一說你為什么想要這本書,就可以參與本次的送書活動(dòng)。


          活動(dòng)規(guī)則:


          1、評(píng)論區(qū)點(diǎn)贊數(shù)量排名靠前的10朋友每人將獲得本次活動(dòng)贈(zèng)送的 1 本書,數(shù)量有限(共10本),大家以評(píng)論點(diǎn)贊排名取勝;


          2、參與活動(dòng)的朋友請(qǐng)留言后轉(zhuǎn)發(fā)本文到朋友圈并添加文末Python小助手微信,開獎(jiǎng)時(shí)小編會(huì)前往核對(duì),沒有轉(zhuǎn)發(fā)的話,獎(jiǎng)品順延到下一位;


          3、活動(dòng)時(shí)間為文章發(fā)布時(shí)間~2020-12-04?18:00;


          4、活動(dòng)贈(zèng)書將由電子工業(yè)出版社博文視點(diǎn)(7 個(gè)工作日)郵寄,開獎(jiǎng)后小編將聯(lián)系中獎(jiǎng)的朋友提供收獲地址,請(qǐng)務(wù)必添加文末Python小助手微信;


          References


          [1]?GeneralNewsExtractor:?https://github.com/kingname/GeneralNewsExtractor

          文:NightTeam團(tuán)隊(duì),本次活動(dòng)最終解釋權(quán)歸Python中文社區(qū)公眾號(hào)所有;

          瀏覽 50
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  99福利导航 | 欧洲色图亚洲色图 | 欧美激情毛片 | 69成人做爰www免费看 | 黄色无码毛片 |