日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

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

python

python爬虫详解

發布時間:2023/12/10 python 70 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python爬虫详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

python爬蟲詳解

1、基本概念

1.1、什么是爬蟲

? ? 網絡爬蟲,是一種按照一定規則,自動抓取互聯網信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動索引、模擬程序或者蠕蟲。隨著網絡的迅速發展,萬維網成為大量信息的載體,如何有效地提取并利用這些信息成為一個巨大的挑戰。例如:傳統的通用搜索引擎AltaVista,Yahoo!和Google等,作為一個輔助人們檢索信息的工具也存在著一定的局限性,通用搜索引擎的目標是盡可能大的網絡覆蓋率,返回的結果包含大量用戶不關心的網頁,為了解決上述問題,定向抓取相關網頁資源的爬蟲應運而生。

? ? 由于互聯網數據的多樣性和資源的有限性,根據用戶需求定向抓取網頁并分析,已成為主流的爬取策略。只要你能通過瀏覽器訪問的數據都可以通過爬蟲獲取,爬蟲的本質是模擬瀏覽器打開網頁,獲取網頁中我們想要的那部分數據。

1.2、Python為什么適合爬蟲

? ? 因為python的腳本特性,python易于配置,對字符的處理也非常靈活,加上python有豐富的網絡抓取模塊,所以兩者經常聯系在一起。

? ??相比與其他靜態編程語言,如java,c#,C++,python抓取網頁文檔的接口更簡潔;相比其他動態腳本語言,如perl,shell,python的urllib2包提供了較為完整的訪問網頁文檔的API。此外,抓取網頁有時候需要模擬瀏覽器的行為,很多網站對于生硬的爬蟲抓取都是封殺的。這是我們需要模擬user agent的行為構造合適的請求,譬如模擬用戶登陸、模擬session/cookie的存儲和設置。在python里都有非常優秀的第三方包幫你搞定,如Requests,mechanize。

? ??抓取的網頁通常需要處理,比如過濾html標簽,提取文本等。python的beautifulsoap提供了簡潔的文檔處理功能,能用極短的代碼完成大部分文檔的處理。

1.3、Python爬蟲組成部分

? ? Python爬蟲架構主要由五個部分組成,分別是調度器、URL管理器、網頁下載器、網頁解析器、應用程序(爬取的有價值數據)。

? ? 調度器:相當于一臺電腦的CPU,主要負責調度URL管理器、下載器、解析器之間的協調工作。
? ? URL管理器:包括待爬取的URL地址和已爬取的URL地址,防止重復抓取URL和循環抓取URL,實現URL管理器主要用三種方式,通過內存、數據庫、緩存數據庫來實現。
? ? 網頁下載器:通過傳入一個URL地址來下載網頁,將網頁轉換成一個字符串,網頁下載器有urllib(Python官方內置標準庫)包括需要登錄、代理、和cookie,requests(第三方包)
? ? 網頁解析器:將一個網頁字符串進行解析,可以按照我們的要求來提取出我們有用的信息,也可以根據DOM樹的解析方式來解析。網頁解析器有正則表達式(直觀,將網頁轉成字符串通過模糊匹配的方式來提取有價值的信息,當文檔比較復雜的時候,該方法提取數據的時候就會非常的困難)、html.parser(Python自帶的)、beautifulsoup(第三方插件,可以使用Python自帶的html.parser進行解析,也可以使用lxml進行解析,相對于其他幾種來說要強大一些)、lxml(第三方插件,可以解析 xml 和 HTML),html.parser 和 beautifulsoup 以及 lxml 都是以 DOM 樹的方式進行解析的。
? ? 應用程序:就是從網頁中提取的有用數據組成的一個應用。

1.4、URI和URL的概念

? ? 在了解爬蟲前,我們還需要了解一下什么是URL?

1.4.1、網頁、網站、網絡服務器、搜素引擎

? ? 網頁:一份網頁文檔是交給瀏覽器顯示的簡單文檔。這種文檔是由超文本標記語言HTML來編寫的,網頁文檔可以插入各種各樣不同類型的資源:

  • 樣式信息?— 控制頁面的觀感
  • 腳本— 為頁面添加交互性
  • 多媒體— 圖像,音頻,和視頻

? ? 網絡上所有可用的網頁都可以通過一個獨一無二的地址訪問到。要訪問一個頁面,只需在你的瀏覽器地址欄中鍵入頁面的地址,即URL。

? ??網站:網站是共享唯一域名的相互鏈接的網頁的集合。給定網站的每個網頁都提供了明確的鏈接—一般都是可點擊文本的形式—允許用戶從一個網頁跳轉到另一個網頁。要訪問網站,請在瀏覽器地址欄中輸入域名,瀏覽器將顯示網站的主要網頁或主頁。

? ??網絡服務器:一個網絡服務器是一臺托管一個或多個網站的計算機。 "托管"意思是所有的網頁和它們的支持文件在那臺計算機上都可用。網絡服務器會根據每位用戶的請求,將任意網頁從托管的網站中發送到任意用戶的瀏覽器中。別把網站和網絡服務器弄混了。例如,當你聽到某人說:"我的網站沒有響應",這實際上指的是網絡服務器沒響應,并因此導致網站不可用。

? ??搜索引擎:搜索引擎是一個特定類型的網站,用以幫助用戶在其他網站中尋找網頁。例如:有Google,?Bing,?Yandex,?DuckDuckGo等等。瀏覽器是一個接收并顯示網頁的軟件,搜索引擎則是一個幫助用戶從其他網站中尋找網頁的網站。

1.4.2、什么是URL

? ? 早在1989年,網絡發明人蒂姆·伯納斯 - 李(Tim Berners-Lee)就提出了網站的三大支柱:

? ? 1)URL?,跟蹤Web文檔的地址系統

? ? 2)HTTP,一個傳輸協議,以便在給定URL時查找文檔

? ? 3)HTML, 允許嵌入超鏈接的文檔格式

? ???Web的最初目的是提供一種簡單的方式來訪問,閱讀和瀏覽文本文檔。從那時起,網絡已經發展到提供圖像,視頻和二進制數據的訪問,但是這些改進幾乎沒有改變三大支柱。

? ??在Web之前,很難訪問文檔并從一個文檔跳轉到另一個文檔。WWW(World Wide Web,萬維網)簡稱為3W,使用統一資源定位符(URL)來標志WWW上的各種文檔。

? ??完整的工作流程如下∶

? ??1)Web用戶使用瀏覽器(指定URL)與Web服務器建立連接,并發送瀏覽請求。

? ? 2)Web服務器把URL轉換為文件路徑,并返回信息給 Web瀏覽器。

? ? 3)通信完成,關閉連接。

? ? HTTP:超文本傳送協議(HTTP)是在客戶程序(如瀏覽器)與WWW服務器程序之間進行交互所使用的協議。HTTP使用統一資源標識符(Uniform Resource Identifiers, URI)來傳輸數據和建立連接,它使用TCP連接進行可靠傳輸,服務器默認監聽在80端口。?

? ? URL:代表統一資源定位器。URL 只不過是 Web 上給定的唯一資源的地址。理論上,每個有效的 URL 都指向一個唯一的資源。此類資源可以是 HTML 頁面、CSS 文檔、圖像等。

? ? URL的組成:

? ? 1)協議部分(http:):它表示瀏覽器必須使用的協議來請求資源(協議是在計算機網絡中交換或傳輸數據的一套方法),通常對于網站,協議是 HTTPS 或 HTTP(其不安全版本)。這里使用的是HTTP協議,在"HTTP"后面的“//”為分隔符;

? ? 2)域名部分(www.example.com):一個URL中,也可以直接使用IP地址;

? ? 3)端口部分(80):域名和端口之間使用“:”作為分隔符。端口不是一個URL必須的部分,如果省略端口部分,將采用默認端口(默認端口可以省略)。

? ? 4)資源路徑:資源路徑包含,虛擬目錄部分和文件名部分

? ? 虛擬目錄部分(/path/to/):從域名后的第一個“/”開始到最后一個“/”為止,是虛擬目錄部分。虛擬目錄也不是一個URL必須的部分。

? ? 文件名部分(myfile.html):從域名后的最后一個“/”開始到“?”為止,是文件名部分,如果沒有“?”,則是從域名后的最后一個“/”開始到“#”為止,是文件部分。

? ? 6)參數部分(key1=value1&key2=value2):從“?”開始到“#”為止之間的部分為參數部分,又稱搜索部分、查詢部分。

? ? 7)錨部分(SomewhereInTheDocument):從“#”開始到最后,都是錨部分。錨點代表資源內的一種“書簽”,為瀏覽器提供顯示位于該“書簽”位置的內容的方向。例如,在 HTML 文檔中,瀏覽器將滾動到定義錨點的位置;在視頻或音頻文檔上,瀏覽器將嘗試轉到錨點所代表的時間。

? ??URI,是uniform resource identifier,統一資源標識符,用來唯一的標識一個資源。URL是uniform resource locator,統一資源定位器,它是一種具體的URI,即URL可以用來標識一個資源,而且還指明了如何locate這個資源。

1.5、引入模塊

? ? ?在進行爬蟲時,我們會用到一些模塊,怎么去使用這些模塊呢?

? ? 模塊(module):就是用來從邏輯上組織Python代碼(變量、函數、類),本質就是py文件,提供代碼的可維護性,Python使用import來導入模塊,如果沒有基礎的可以先看這篇文章:https://blog.csdn.net/xiaoxianer321/article/details/116723566。

? ? 導入模塊:

#導入內置模塊 import sys #導入標準庫 import os #導入第三方庫(需要安裝:pip install bs4) import bs4 from bs4 import BeautifulSoupprint(os.getcwd()) #打印當前工作目錄 #import bs4 導入整個模塊 print(bs4.BeautifulSoup.getText) #from bs4 import BeautifulSoup 導入指定模塊的部分屬性至當前工作空間 print(BeautifulSoup.getText)

安裝方式1:在終端中使用命令

安裝方式二:pycharm在設置中安裝

? ? 我們大概會用到以下這些模塊:

import urllib.request,urllib.error #定制URL,獲取網頁數據 from bs4 import BeautifulSoup #網頁解析,獲取數據 import re #正則表達式,進行文件匹配 import xlwt #進行excel操作 import sqlite3 #進行SQLite數據庫操作

2、urllib庫詳解

? ? Python3 中將 Python2 中的 urllib 和 urllib2 兩個庫整合為一個 urllib 庫,所以現在一般說的都是 Python3 中的 urllib 庫,它是python3內置標準庫,不需要額外安裝。

? ??urllib的四個模塊:

2.1、request模塊

? ??request模塊提供了最基本的構造 HTTP 請求的方法,利用它可以模擬瀏覽器的一個請求發起過程,同時它還帶有處理authenticaton(授權驗證),redirections(重定向),cookies(瀏覽器Cookies)以及其它內容。

2.1.1、urllib.request.urlopen() 函數

? ??打開一個url方法,返回一個文件對象HttpResponse。urlopen默認會發送get請求,當傳入data參數時,則會發起POST請求。

語法: urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)參數說明: url:請求的 url,也可以是request對象 data:請求的 data,如果設置了這個值,那么將變成 post 請求,如果要傳遞一個字典,則應該用urllib.parse模塊的urlencode()函數編碼; timeout:設置網站的訪問超時時間句柄對象; cafile和capath:用于 HTTPS 請求中,設置 CA 證書及其路徑; cadefault:忽略*cadefault*參數; context:如果指定了*context*,則它必須是一個ssl.SSLContext實例。urlopen() 返回對象HTTPResponse提供的方法和屬性:1)read()、readline()、readlines()、fileno()、close():對 HTTPResponse 類型數據進行操作; 2)info():返回 HTTPMessage 對象,表示遠程服務器 返回的頭信息 ; 3)getcode():返回 HTTP 狀態碼 geturl():返回請求的 url; 4)getheaders():響應的頭部信息; 5)status:返回狀態碼; 6)reason:返回狀態的詳細信息.

案例一:使用urlopen()函數抓取百度

import urllib.request url = "http://www.baidu.com/" res = urllib.request.urlopen(url) # get方式請求 print(res) # 返回HTTPResponse對象<http.client.HTTPResponse object at 0x00000000026D3D00> # 讀取響應體 bys = res.read() # 調用read()方法得到的是bytes對象。 print(bys) # <!DOCTYPE html><!--STATUS OK-->\n\n\n <html><head><meta... print(bys.decode("utf-8")) # 獲取字符串內容,需要指定解碼方式,這部分我們放到html文件中就是百度的主頁# 獲取HTTP協議版本號(10 是 HTTP/1.0, 11 是 HTTP/1.1) print(res.version) # 11# 獲取響應碼 print(res.getcode()) # 200 print(res.status) # 200# 獲取響應描述字符串 print(res.reason) # OK# 獲取實際請求的頁面url(防止重定向用) print(res.geturl()) # http://www.baidu.com/# 獲取響應頭信息,返回字符串 print(res.info()) # Bdpagetype: 1 Bdqid: 0x803fb2b9000fdebb... # 獲取響應頭信息,返回二元元組列表 print(res.getheaders()) # [('Bdpagetype', '1'), ('Bdqid', '0x803fb2b9000fdebb'),...] print(res.getheaders()[0]) # ('Bdpagetype', '1') # 獲取特定響應頭信息 print(res.getheader(name="Content-Type")) # text/html;charset=utf-8

? ? 在簡單的了解了一下使用urllib.request.urlopen(url)函數,會返回一個HTTPResponse對象,對象中包含了請求后響應的各項信息。

? ? 請求url最常見的方式莫過于發送get請求或post請求,為了更方便的看到效果,我們可以使用這個網站http://httpbin.org/來測試我們的請求。

案例二:get請求

我們在http://httpbin.org/網站,發送一個get測試請求:

然后我們在使用python模擬瀏覽器發送一個get請求

import urllib.request # 請求的URL url = "http://httpbin.org/get" # 模擬瀏覽器打開網頁(get請求) res = urllib.request.urlopen(url) print(res.read().decode("utf-8"))

?請求結果如下:

我們會發現python模擬瀏覽器的請求很像。

?案例三:pos請求

import urllib.request import urllib.parseurl = "http://httpbin.org/post" # 按POST請求的格式封裝數據,請求內容,需要傳遞data data = bytes(urllib.parse.urlencode({"hello": "world"}), encoding="utf-8") res = urllib.request.urlopen(url, data=data) # 輸出響應結果 print(res.read().decode("utf-8"))

模擬瀏覽器發出的請求(提交的數據會以form表單的形式發送出去),響應結果如下:

{"args": {}, "data": "", "files": {}, "form": {"hello": "world"}, "headers": {"Accept-Encoding": "identity", "Content-Length": "11", "Content-Type": "application/x-www-form-urlencoded", "Host": "httpbin.org", "User-Agent": "Python-urllib/3.8", "X-Amzn-Trace-Id": "Root=1-60e0754e-7ea455cc757714f14db8f2d2"}, "json": null, "origin": "183.216.63.84", "url": "http://httpbin.org/post" }

案例四:?偽裝Headers

? ? 通過上面的案例,不難發現使用urllib發送的請求,比較不同的地方是:"User-Agent",使用urllib發送的會有一個默認的Headers:User-Agent: Python-urllib/3.8所以遇到一些驗證User-Agent的網站時,有可能會直接拒絕爬蟲,因此我們需要自定義Headers把自己偽裝的像一個瀏覽器一樣

? ? 其實我們使用抓包工具也能看到http請求,使用抓包工具,抓取未指定請求頭的get請求如下:

? ? 而我直接使用谷歌瀏覽器時,使用抓包工具獲取到的User-Agent如下:

? ? 當然也可以直接在瀏覽器中查看:

?例如:我去爬取豆瓣網時:

import urllib.requesturl = "http://douban.com" resp = urllib.request.urlopen(url) print(resp.read().decode('utf-8'))返回錯誤:反爬蟲 raise HTTPError(req.full_url, code, msg, hdrs, fp) urllib.error.HTTPError: HTTP Error 418: HTTP 418 I'm a teapot客戶端錯誤響應代碼表示服務器拒絕煮咖啡,因為它是一個茶壺。這個錯誤是對1998年愚人節玩笑的超文本咖啡壺控制協議的引用。

? ? 自定義Headers:

import urllib.requesturl = "http://douban.com" # 自定義headers headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36' } req = urllib.request.Request(url, headers=headers) # urlopen(也可以是request對象) print(urllib.request.urlopen(req).read().decode('utf-8')) # 獲取字符串內容,需要指定解碼方式

? ? 當我再次使用抓包工具,抓取指定請求頭的get請求,結果如下:

案例五:設置請求超時時間

? ? ?我們在爬取網頁時,難免會遇到請求超時,或者無法響應的網址,為了提高代碼的健壯性,我可以設置請求超時時間。

import urllib.request,urllib.errorurl = "http://httpbin.org/get" try:resp = urllib.request.urlopen(url, timeout=0.01)print(resp.read().decode('utf-8')) except urllib.error.URLError as e:print("time out")輸出:time out

2.1.2、urllib.request.urlretrieve()?函數

? ??urlretrieve()函數的作用是直接將遠程的數據下載到本地

# 語法:urlretrieve(url, filename=None, reporthook=None, data=None)# 參數說明url:傳入的網址 filename:指定了保存本地路徑(如果參數未指定,urllib會生成一個臨時文件保存數據) reporthook:是一個回調函數,當連接上服務器、以及相應的數據塊傳輸完畢時會觸發該回調,我們可以利用這個回調函數來顯示當前的下載進度 data:指 post 到服務器的數據,該方法返回一個包含兩個元素的(filename, headers)元組,filename 表示保存到本地的路徑,header表示服務器的響應頭

使用案例:

import urllib.requesturl = "http://www.hao6v.com/" filename = "C:\\Users\\Administrator\\Desktop\\python_3.8.5\\電影.html" def callback(blocknum,blocksize,totalsize):"""@blocknum:目前為此傳遞的數據塊數量@blocksize:每個數據塊的大小,單位是byte,字節@totalsize:遠程文件的大小"""if totalsize == 0:percent = 0else:percent = blocknum * blocksize / totalsizeif percent > 1.0:percent = 1.0percent = percent * 100print("download : %.2f%%" % (percent))local_filename, headers= urllib.request.urlretrieve(url, filename, callback)

案例效果:

2.2、error模塊

? ??urllib.error 模塊為 urllib.request 所引發的異常定義了異常類,基礎異常類是 URLError。

2.2.1、HTTP協議(RFC2616)狀態碼定義

? ? 所有HTTP響應的第一行都是狀態行,依次是當前HTTP版本號,3位數字組成的狀態代碼,以及描述狀態的短語,彼此由空格分隔。?

? ? 狀態代碼的第一個數字代表當前響應的類型:

? ? 1xx消息——請求已被服務器接收,繼續處理
? ? 2xx成功——請求已成功被服務器接收、理解、并接受
? ? 3xx重定向——需要后續操作才能完成這一請求
? ? 4xx請求錯誤——4xx類的狀態碼用于看起來客戶端有錯誤的情況下,請求含有詞法錯誤或者無法被執行
? ? 5xx服務器錯誤——由數字“5”打頭的響應狀態碼表示服務器已經明顯處于錯誤的狀況下或沒有能力執行請求,或在處理某個正確請求時發生錯誤。

部分狀態碼如下:

狀態碼定義
100繼續。客戶端應該繼續它的請求。該間歇響應用于提醒客戶端服務器已經接收和接受請求的開
始部分。 客戶端應該繼續發送請求的剩余部分, 或者如果請求已經發送完了, 就乎略該響應。
服務器在請求完成后必須發送最終響應。
101切換協議。
200OK。請求已經成功。該響應返回的信息取決于請求中使用的方法,例如:
GET與所請求資源相對應的實體將在響應中發送;
HEAD 與所請求資源相對應的實體頭部將在響應中發送,而沒有消息體;
POST描述或包含行為結果的實體;
TRACE 包含終點服務器收到的請求消息的實體。
201創建。請求全部成功,且創建了新資源。原始服務器必須在返回 201 狀態碼之前創建資源。 如果該行為不能立即實施,服務器應該代之以202(Accepted)響應。
202請求已經接受處理,但是處理還沒有完成。
203實體頭部中返回的元信息不是在原始服務器有效的確定集合, 而是從本地或第三方拷貝
收集的。現在的集合可能是原始版本的子集或超集。
204服務器已經完成請求,但不需要返回實體,且可能希望返回更新的元信息。響應可能包
括新的或更新的元信息,通過實體頭部的形式。如果存在這些頭部,則應該與所請求變量相
關。
205重置內容。服務器已經完成請求且用戶代理應該復位引起請求發送的文檔視圖。
300多重選項。所請求的資源符合表述集合中的任何一個,每個都有它自己的特殊位置。代理驅動的協
商信息提供給用戶(或用戶代理)來選擇喜歡的表述,并重定向請求到它的位置。?
301所請求的資源已經指定到一個新的永久 URI, 且將來任何對該資源的引用都應該使用所
返回的 URI 之一。
302?所請求的資源臨時存在于不同的 URI。
303請求的響應可以在不同的URI中發現,且應該使用GET方法到該資源來獲取它。
307臨時重定向
400?服務器不能理解請求,由于畸形的語法。
403服務器理解請求, 但拒絕完成它。 認證也沒用, 請求不該重復。
404未找到。服務器不能發現匹配Request-URI的任何東西。
408請求超時
500服務器錯誤
503

服務不可用

504網關超時
505HTTP版本不支持

2.2.2、?urllib.error.URLError

import urllib.request,urllib.errortry:url = "http://www.baidus.com"resp = urllib.request.urlopen(url)print(resp.read().decode('utf-8')) # except urllib.error.HTTPError as e: # print("請檢查url是否正確") # URLError是urllib.request異常的超類 except urllib.error.URLError as e:if hasattr(e, "code"):print(e.code)if hasattr(e, "reason"):print(e.reason)

案例效果:

? ? ?URLError,為urllib.request 所引發的基礎異常類,這里打印出來的403,就是urllib.error.HTTPError,另外還有一個ContentTooShortError,此異常會在 urlretrieve() 函數檢測到已下載的數據量小于期待的數據量(由 Content-Length 頭給定)時被引發。?

2.3、parse 模塊

? ? urllib.parse 模塊提供了很多解析和組建 URL 的函數。下面只列出了部分
? ? 解析url的函數:urllib.parse.urlparse、urllib.parse.urlsplit、urllib.parse.urldefrag

? ? 組件url的函數:urllib.parse.urlunparse、urllib.parse.urljoin

????查詢參數的構造與解析:urllib.parse.urlencode、urllib.parse.parse_qs、

urllib.parse.parse_qsl

2.3.1、urllib.parse.urlparse

# 語法 urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)scheme:設置默認值 allow_fragments:是否允許fragment

? ? ?將URL解析成 ParseResult 對象。對象中包含了六個元素:也就是我們前面說過的url的組成,只不過urlparse函數,將其解析成6個元素。

屬性

索引

值(如果不存在)

scheme

0

URL協議

scheme?參數

netloc

1

網絡位置部分(域名)

空字符串

path

2

分層路徑

空字符串

params

3

最后路徑元素的參數

空字符串

query

4

查詢參數

空字符串

fragment

5

片段識別

空字符串

?使用案例:

import urllib.parseurl = "http://www.example.com:80/path/to/myfile.html?key1=value&key2=value2#SomewhereIntheDocument" parsed_result = urllib.parse.urlparse(url) print(parsed_result) print('協議-scheme :', parsed_result.scheme) print('域名-netloc :', parsed_result.netloc) print('路徑-path :', parsed_result.path) print('路徑參數-params :', parsed_result.params) print('查詢參數-query :', parsed_result.query) print('片段-fragment:', parsed_result.fragment) print('用戶名-username:', parsed_result.username) print('密碼-password:', parsed_result.password) print('主機名-hostname:', parsed_result.hostname) print('端口號-port :', parsed_result.port)輸出結果: ParseResult(scheme='http', netloc='www.example.com:80', path='/path/to/myfile.html', params='', query='key1=value&key2=value2', fragment='SomewhereIntheDocument') 協議-scheme : http 域名-netloc : www.example.com:80 路徑-path : /path/to/myfile.html 路徑參數-params : 查詢參數-query : key1=value&key2=value2 片段-fragment: SomewhereIntheDocument 用戶名-username: None 密碼-password: None 主機名-hostname: www.example.com 端口號-port : 80

2.3.2、urllib.parse.urlsplit

? ? 這類似于urlparse,所不同的是, urlsplit() 并不會把路徑參數(params) 從 路徑(path) 中分離出來。此函數返回一個名為tuple的5項:(協議、域名、路徑、查詢、片段標識符)

使用案例:

import urllib.parseurl = "http://www.example.com:80/path/to/myfile.html?key1=value&key2=value2#SomewhereIntheDocument" # urlsplit分割,唯一的區別就是不會把params拆分出來 parsed_result = urllib.parse.urlsplit(url) print(parsed_result) print('協議-scheme :', parsed_result.scheme) print('域名-netloc :', parsed_result.netloc) print('路徑-path :', parsed_result.path) # parsed_result.params 沒有這項 print('查詢參數-query :', parsed_result.query) print('片段-fragment:', parsed_result.fragment) print('用戶名-username:', parsed_result.username) print('密碼-password:', parsed_result.password) print('主機名-hostname:', parsed_result.hostname) print('端口號-port :', parsed_result.port)

2.3.3、urllib.parse.urlsplit?

? ? urllib.parse.urldefrag,如果url包含片段標識符,則返回修改后的url版本(不包含片段標識符),并將片段標識符作為單獨的字符串返回。如果url中沒有片段標識符,則返回原url和空字符串。

使用案例:

import urllib.parseurl = "http://www.example.com:80/path/to/myfile.html?key1=value&key2=value2#SomewhereIntheDocument" parsed_result = urllib.parse.urldefrag(url) print(parsed_result) # DefragResult(url='http://www.example.com:80/path/to/myfile.html?key1=value&key2=value2', fragment='SomewhereIntheDocument') url1 = "http://www.example.com:80/path/to/myfile.html?key1=value&key2=value2" parsed_result1 = urllib.parse.urldefrag(url1) print(parsed_result1)# 輸出結果: # DefragResult(url='http://www.example.com:80/path/to/myfile.html?key1=value&key2=value2', fragment='SomewhereIntheDocument') # DefragResult(url='http://www.example.com:80/path/to/myfile.html?key1=value&key2=value2', fragment='')

2.3.4、urllib.parse.urlunparse

? ??urlunparse()接收一個列表的參數,而且列表的長度是有要求的,是必須六個參數以上,否則拋出異常。

import urllib.parseurl_compos = ('http', 'www.example.com:80', '/path/to/myfile.html', 'params2', 'query=key1=value&key2=value2', 'SomewhereIntheDocument') print(urllib.parse.urlunparse(url_compos))# 輸出結果: # http://www.example.com:80/path/to/myfile.html;params2?query=key1=value&key2=value2#SomewhereIntheDocument

2.3.5、urllib.parse.urljoin

import urllib.parse# 連接兩個參數的url, 將第二個參數中缺的部分用第一個參數的補齊,如果第二個有完整的路徑,則以第二個為主。 print(urllib.parse.urljoin('https://movie.douban.com/', 'index')) print(urllib.parse.urljoin('https://movie.douban.com/', 'https://accounts.douban.com/login'))# 輸出結果: # https://movie.douban.com/index # https://accounts.douban.com/login

2.3.6、urllib.parse.urlencode

? ? 可以將一個 dict 轉換成合法的查詢參數。

import urllib.parsequery_args = {'name': 'dark sun','country': '中國' } query_args = urllib.parse.urlencode(query_args) print(query_args)# 輸出結果 # name=dark+sun&country=%E4%B8%AD%E5%9B%BD

2.3.7、urllib.parse.parse_qs

? ? 解析作為字符串參數提供的查詢字符串,數據作為字典返回。字典鍵是唯一的查詢變量名,值是每個名稱的值列表。

import urllib.parsequery_args = {'name': 'dark sun','country': '中國' } query_args = urllib.parse.urlencode(query_args) print(query_args) # name=dark+sun&country=%E4%B8%AD%E5%9B%BDprint(urllib.parse.parse_qs(query_args)) # 返回字典 print(urllib.parse.parse_qsl(query_args)) # 返回列表# 輸出結果 # {'name': ['dark sun'], 'country': ['中國']} # [('name', 'dark sun'), ('country', '中國')]

2.4、robotparser模塊

? ? 此模塊提供了一個單獨的類?RobotFileParser,它可以回答關于某個特定用戶代理是否能在 Web 站點獲取發布?robots.txt?文件的 URL 的問題。(/robots.txt該文件是一個簡單的基于文本的訪問控制系統,文件向網絡機器人提供有關其網站的說明,什么機器人可以訪問,哪些鏈接不可以訪問)

3、BeautifulSoup4

? ??學了urllib標準庫之后,我們已經能爬到些比較正常的網頁源碼(html文檔)了,但這離結果還差一步——就是如何篩選我們想要的數據,這時候BeautifulSoup庫就來了,BeautifulSoup目前最新版本為BeautifulSoup4。

3.1、BeautifulSoup4的簡介及使用

3.1.1、BeautifulSoup4的簡介

? ? Beautiful Soup 官方定義:是一個可以從HTML或XML文件中提取數據的Python庫.它能夠通過你喜歡的轉換器實現慣用的文檔導航,查找,修改文檔的方式.Beautiful Soup會幫你節省數小時甚至數天的工作時間。(官網文檔:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/)

? ??BeautifulSoup本身支持Python標準庫中的HTML解析器,但若想使BeautifulSoup使用html5lib/lxml 解析器解析器,可以使用下面方法。(官方推薦:使用lxml作為解析器,因為效率更高。)

pip install html5lib pip install lxml

3.1.2、BeautifulSoup4的使用

? ? ?BeautifulSoup(markup, features)接受兩個參數:

? ? ?第一個參數(markup):文件對象或字符串對象

? ? ?第二個參數(features):解析器,未指定則使用python標準解析器(html.parser),但會產警告

from bs4 import BeautifulSoup # 導入BeautifulSoup4庫# 未指定就使用html.parser這個python標準解析器 BeautifulSoup(markup, "html.parser") 未指定會產生警告 GuessedAtParserWarning: No parser was explicitly specified# BeautifulSoup 第一個參數接受:一個文件對象或字符串對象 soup1 = BeautifulSoup(open("C:\\Users\\Administrator\\Desktop\\python_3.8.5\\電影.html")) soup2 = BeautifulSoup("<html>hello python</html>") # 得到文檔的對象 print(type(soup2)) # <class 'bs4.BeautifulSoup'> print(soup1) # <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" .... print(soup2) # <html><head></head><body>hello python</body></html>

3.2、對象的種類

? ? ?BeautifulSoup將復雜HTML文檔轉換成一個復雜的樹形結構,每個節點都是Python對象,所有對象可以歸納為4種: Tag , NavigableString , BeautifulSoup , Comment 。

3.2.1、Tag 標簽對象

? ??Tag有很多方法和屬性,在?遍歷文檔樹?和?搜索文檔樹?中有詳細解釋.現在介紹一下tag中最重要的屬性: name和attribute。

3.2.2、NavigableString 對象(可以遍歷的字符串)

? ?被包含在一個標簽對中的字符串內容,可用tag.string來獲取其內容(標簽內容中含注釋或其他標簽均無法獲取)

3.2.3、BeautifulSoup 對象

? ??表示的是一個文檔(document)的全部內容

3.2.4、Comment?對象(注釋及特殊字符串)

? ??Comment 對象是一個特殊類型的 NavigableString 對象,其實輸出的內容仍然不包括注釋符號,但是如果不好好處理它,可能會對我們的文本處理造成意想不到的麻煩。

使用案例:

from bs4 import BeautifulSoup # 導入BeautifulSoup4庫 # python 標準解析器 未指定就使用這個 BeautifulSoup(markup, "html.parser") soup2 = BeautifulSoup("<html>""<p class='boldest'>我是p標簽<b>hello python</b></p>""<!--我是標簽外部的內容注釋-->""<p class='boldest2'><!--我p標簽內的注釋-->我是獨立的p標簽</p>""<a><!--我a標簽內的注釋-->我是鏈接</a>""<h1><!--這是一個h1標簽的注釋--></h1>""</html>","html5lib") # 得到文檔的對象 # Tag 標簽對象 print(type(soup2.p)) # 輸出Tag對象<class 'bs4.element.Tag'> print(soup2.p.name) # 輸出Tag標簽對象的名稱 print(soup2.p.attrs) # 輸出第一個p標簽的屬性信息:{'class': ['boldest']} soup2.p['class'] = ['boldest', 'boldest1'] print(soup2.p.attrs) # {'class': ['boldest', 'boldest1']}# NavigableString 可以遍歷的字符串對象 print(type(soup2.b.string)) # <class 'bs4.element.NavigableString'> print(soup2.b.string) # hello python print(soup2.a.string) # None 存在注釋或者其他標簽內容均無法獲取 print(soup2.b.string.replace_with("hello world")) # replace_with()方法可替換標簽中的內容 print(soup2.b.string) # hello world# BeautifulSoup 對象 print(type(soup2)) # <class 'bs4.BeautifulSoup'> print(soup2) # <html><head></head><body><p class="boldest">我是p標簽<b>hello python</b></p><!--我是標簽外部的內容注釋--><p><!--我p標簽內的注釋-->我是獨立的p標簽</p></body></html> print(soup2.name) # [document]# Comment 注釋及特殊字符串(是一個特殊類型的 NavigableString 對象) print(type(soup2.h1.string)) # <class 'bs4.element.Comment'> print(soup2.h1.string) # 這是一個h1標簽的注釋 (利用 .string 來輸出它的內容,注釋符被去除了,不是我們想要的) print(soup2.h1.prettify()) # 會以特殊格式輸出:<h1> <!--這是一個h1標簽的注釋--> </h1>

3.3、對象屬性-遍歷文檔

3.3.1、子節點

屬性(BeautifulSoup對象描述
.tag標簽名使用標簽名獲取一個標簽及其內容
.contents / .chidren將tag的子節點以列表的方式輸出
.descendants可以對所有tag的子孫節點進行遞歸循環
.string如果tag只有一個 NavigableString 類型子節點,那么這個tag可以使用 .string 得到子節點
.strings/stripped_stringstag中有多個字符串,可以使用.strings來循環獲取stripped_strings可以去除多余空白內容

使用案例:

from bs4 import BeautifulSoupmarkup = '''<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>I’m the title</title></head><body><h1>HelloWorld</h1><div><div><p><b>我是一個段落...</b>我是第一段我是第二段<b>我是另一個段落</b>我是第一段</p><a>我是一個鏈接</a></div><div><p>picture</p><img src="example.png"/></div></div></body> </html>''' soup = BeautifulSoup(markup, "html5lib") # BeautifulSoup 對象 print(soup.head.name) # soup.head可以獲取標簽,獲取標簽名 - 輸出:head print(soup.head.contents) # 將tag的子節點以列表的方式輸出--輸出:['\n ', <meta charset="utf-8"/>, '\n ', <title>I’m the title</title>, '\n '] print(soup.head.contents[1]) # <meta charset="utf-8"/> print(soup.head.children) # list_iterator object for child in soup.head.children:print(child) # <meta charset="utf-8"/> <title>I’m the title</title> # 標簽中的內容其實也是一個節點 使用contents和children無法直接獲取間接節點中的內容,但是.descendants 屬性可以 for child in soup.head.descendants:print(child) # <meta charset="utf-8"/> <title>I’m the title</title> I’m the title print(soup.head.title.string) # 輸出:I’m the title 注:title中有其他節點或者注釋都無法獲取print(soup.body.div.div.p.strings) # 使用.string-None 使用.strings 獲得generator object for string in soup.body.div.div.p.stripped_strings: # stripped_strings 可以去除多余空白內容print(repr(string)) # '我是一個段落...'# '我是第一段\n 我是第二段'# '我是另一個段落'# '我是第一段'

3.3.2、父節點

屬性描述
.parent獲取某個元素的父節點
.parents可以遞歸得到元素的所有父輩節點

使用案例:

from bs4 import BeautifulSoupmarkup = '''<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>I’m the title</title></head><body><h1>HelloWorld</h1><div><div><p><b>我是一個段落...</b>我是第一段我是第二段<b>我是另一個段落</b>我是第一段</p><a>我是一個鏈接</a></div><div><p>picture</p><img src="example.png"/></div></div></body> </html>''' soup = BeautifulSoup(markup, "html5lib") # BeautifulSoup 對象 title = soup.head.title print(title.parent) # 輸出父節點 # <head> # <meta charset="utf-8"/> # <title>I’m the title</title> # </head> print(title.parents) # generator object PageElement.parents for parent in title.parents:print(parent) # 輸出head父節點 和 html父節點

3.3.3、兄弟節點

屬性描述
.next_sibling查詢兄弟節點,表示下一個兄弟節點
.previous_sibling查詢兄弟節點,表示上一個兄弟節點
.next_siblings對當前節點的兄弟節點迭代輸出(下)
.previous_siblings對當前節點的兄弟節點迭代輸出(上)

使用案例:

from bs4 import BeautifulSoupmarkup = '''<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>I’m the title</title></head><body><div><p><b id=“b1”>我是第一個段落</b><b id=“b2”>我是第二個段落</b><b id=“b3”>我是第三個段落</b><b id=“b4”>我是第四個段落</b></p><a>我是一個鏈接</a></div></body> </html>''' soup = BeautifulSoup(markup, "html5lib") # BeautifulSoup 對象 p = soup.body.div.p.b print(p) # <b id="“b1”">我是第一個段落</b> print(p.next_sibling) # <b id="“b2”">我是第二個段落</b> print(p.next_sibling.previous_sibling) # <b id="“b1”">我是第一個段落</b> print(p.next_siblings) # generator object PageElement.next_siblings for nsl in p.next_siblings:print(nsl) # <b id="“b2”">我是第二個段落</b># <b id="“b3”">我是第三個段落</b># <b id="“b4”">我是第四個段落</b>

3.3.4、回退和前進

屬性描述
.next_element解析下一個元素對象
.previous_element解析上一個元素對象
.next_elements迭代解析元素對象
.previous_elements迭代解析元素對象

使用案例:

from bs4 import BeautifulSoupmarkup = '''<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>I’m the title</title></head><body><div><p><b id=“b1”>我是第一個段落</b><b id=“b2”>我是第二個段落</b><b id=“b3”>我是第三個段落</b><b id=“b4”>我是第四個段落</b></p><a>我是一個鏈接<h3>h3</h3></a></div></body> </html>''' soup = BeautifulSoup(markup, "html5lib") # BeautifulSoup 對象 p = soup.body.div.p.b print(p) # <b id="“b1”">我是第一個段落</b> print(p.next_element) # 我是第一個段落 print(p.next_element.next_element) # <b id="“b2”">我是第二個段落</b> print(p.next_element.next_element.next_element) # 我是第二個段落 for element in soup.body.div.a.next_element: # 對:我是一個鏈接 字符串的遍歷print(element)

? ? 注:next_element,會把標簽中的內容,也會認為是一個節點。例如:案例中取a節點的next_element,則是一個字符串(我是一個鏈接)

3.4、對象的屬性和方法-搜索文檔樹

? ? 這里的搜索文檔,其實就是按照某種條件去搜索過濾文檔,過濾的規則,往往會使用搜索的API,或者我們也可以自定義正則/過濾器,去搜索文檔。

3.4.1、find_all()

? ??最簡單的過濾器是字符串.在搜索方法中傳入一個字符串參數,Beautiful Soup會查找與字符串完整匹配的內容。

語法:find_all(?name?,?attrs?,?recursive?,?string?,?**kwargs?)? 返回列表list

find_all(?name?,?attrs?,?recursive?,?string?,?**kwargs?)?參數說明: name:查找所有名字為 name 的tag(name可以是字符串,也可以是列表) attrs: 對標簽屬性值的檢索字符串,可標注屬性檢索 recursive: 是否對子孫全部檢索,默認True string: <>…</>中字符串區域的檢索字符串

使用案例:

from bs4 import BeautifulSoup import remarkup = '''<!DOCTYPE html> <html><head><meta charset="UTF-8"><title id="myTitle">I’m the title</title></head><body><div><p><b id=“b1” class="bcl1">我是第一個段落</b><b>我是第二個段落</b><b id=“b3”>我是第三個段落</b><b id=“b4”>我是第四個段落</b></p><a href="www.temp.com">我是一個鏈接<h3>h3</h3></a><div id="dv1">str</div></div></body> </html>''' # 語法:find_all( name , attrs , recursive , string , **kwargs ) soup = BeautifulSoup(markup, "html5lib") # BeautifulSoup 對象 # 第一個參數name,可以是一個標簽名也可以是列表 print(soup.findAll('b')) # 返回包含b標簽的列表 [<b id="“b1”">我是第一個段落</b>, <b id="“b2”">我是第二個段落</b>, <b id="“b3”">我是第三個段落</b>, <b id="“b4”">我是第四個段落</b>] print(soup.findAll(['a', 'h3'])) # 按列表匹配多個 [<a href="www.temp.com">我是一個鏈接<h3>h3</h3></a>, <h3>h3</h3>]# 第二個參數attrs,可以指定參數名字,也可以不指定 print(soup.findAll('b', 'bcl1')) # 匹配class='bcl1'的b標簽[<b class="bcl1" id="“b1”">我是第一個段落</b>] print(soup.findAll(id="myTitle")) # 指定id [<title id="myTitle">I’m the title</title>] print(soup.find_all("b", attrs={"class": "bcl1"})) # [<b class="bcl1" id="“b1”">我是第一個段落</b>] print(soup.findAll(id=True)) # 匹配所有有id屬性的標簽# 第三個參數recursive 默認True 如果只想搜索tag的直接子節點,可以使用參數 recursive=False print(soup.html.find_all("title", recursive=False)) # [] recursive=False。找html的直接子節點,是head,所以找不到title# 第四個參數string print(soup.findAll('div', string='str')) # [<div id="dv1">str</div>] print(soup.find(string=re.compile("我是第二個"))) # 搜索我是第二個段落# 其他參數 limit 參數 print(soup.findAll('b', limit=2)) # 當搜索到的結果數量達到 limit 的限制時,就停止搜索返回結果,[<b class="bcl1" id="“b1”">我是第一個段落</b>, <b>我是第二個段落</b>]

?3.4.2、find()?

? ??find()與find_all()?的區別是?find_all()?方法的返回結果是值包含一個元素的列表,而?find()?方法直接返回結果(即找到了就不再找,只返第一個匹配的),find_all()?方法沒有找到目標是返回空列表,?find()?方法找不到目標時,返回?None。

? ? 語法:find(?name?,?attrs?,?recursive?,?string?,?**kwargs?)

使用案例:

soup = BeautifulSoup(markup, "html5lib") # BeautifulSoup 對象 # 第一個參數name,可以是一個標簽名也可以是列表 print(soup.find('b')) # 返回<b class="bcl1" id="“b1”">我是第一個段落</b>,只要找到一個即返回# 第二個參數attrs,可以指定參數名字,也可以不指定 print(soup.find('b', 'bcl1')) # <b class="bcl1" id="“b1”">我是第一個段落</b> print(soup.find(id="myTitle")) # <title id="myTitle">I’m the title</title> print(soup.find("b", attrs={"class": "bcl1"})) # <b class="bcl1" id="“b1”">我是第一個段落</b> print(soup.find(id=True)) # 匹配到第一個<title id="myTitle">I’m the title</title># 第三個參數recursive 默認True 如果只想搜索tag的直接子節點,可以使用參數 recursive=False print(soup.html.find("title", recursive=False)) # None recursive=False。找html的直接子節點,是head,所以找不到title# 第四個參數string print(soup.find('div', string='str')) # [<div id="dv1">str</div>] print(soup.find(string=re.compile("我是第二個"))) # 我是第二個段落

3.4.3、find_parents() 和 find_parent()

? ??find_parents()?和?find_parent()?用來搜索當前節點的父輩節點。

? ? 語法:

? ? find_parents(?name?,?attrs?,?recursive?,?string?,?**kwargs?)

? ? find_parent(?name?,?attrs?,?recursive?,?string?,?**kwargs?)

3.4.4、find_next_siblings() 和 find_next_sibling()

? ??find_next_siblings()?方法返回所有符合條件的后面的兄弟節點,find_next_sibling()?只返回符合條件的后面的第一個tag節點;

? ? 語法:

? ??find_next_siblings(?name?,?attrs?,?recursive?,?string?,?**kwargs?)

? ? find_next_sibling(?name?,?attrs?,?recursive?,?string?,?**kwargs?)

3.4.5、find_previous_siblings() 和 find_previous_sibling()

? ??通過?.previous_siblings?屬性對當前tag的前面解析。find_previous_siblings()?方法返回所有符合條件的前面的兄弟節點,find_previous_sibling()?方法返回第一個符合條件的前面的兄弟節點;

? ? 語法:

? ? find_previous_siblings(?name?,?attrs?,?recursive?,?string?,?**kwargs?)

? ? find_previous_sibling(?name?,?attrs?,?recursive?,?string?,?**kwargs?)

3.4.6、find_all_next() 和 find_next()

? ??find_all_next()?方法返回所有符合條件的節點,find_next()?方法返回第一個符合條件的節點。

? ? ?語法:

? ??find_all_next(?name?,?attrs?,?recursive?,?string?,?**kwargs?)

? ? find_next(?name?,?attrs?,?recursive?,?string?,?**kwargs?)

3.4.7、find_all_previous() 和 find_previous()

? ??find_all_previous()?方法返回所有符合條件的節點元素,find_previous()?方法返回第一個符合條件的節點元素。

? ? 語法:

? ? find_all_previous(?name?,?attrs?,?recursive?,?string?,?**kwargs?)

? ? find_previous(?name?,?attrs?,?recursive?,?string?,?**kwargs?)

? ? 這些其實和前面的屬性用法類似,但是比屬性又多了像find_all()一樣的參數。這里就不再詳細介紹了,可以看官網的API。

3.4.8、CSS選擇器查找

? ??Beautiful Soup支持大部分的CSS選擇器,在?Tag?或?BeautifulSoup?對象的?.select()?方法中傳入字符串參數, 即可使用CSS選擇器的語法找到tag。

使用案例:

from bs4 import BeautifulSoup import remarkup = '''<!DOCTYPE html> <html><head><meta charset="UTF-8"><title id="myTitle">I’m the title</title></head><body><div><p><b id=“b1” class="bcl1">我是第一個段落</b><b>我是第二個段落</b><b id=“b3”>我是第三個段落</b><b id=“b4”>我是第四個段落</b></p><a href="www.temp.com">我是一個鏈接<h3>h3</h3></a><div id="dv1">str</div></div></body> </html>''' soup = BeautifulSoup(markup, "html5lib") # BeautifulSoup 對象 print(soup.select("html head title")) # [<title id="myTitle">I’m the title</title>] print(soup.select("body a")) # [<a href="www.temp.com">我是一個鏈接<h3>h3</h3></a>] print(soup.select("#dv1")) # [<div id="dv1">str</div>]

3.5、對象的屬性和方法-修改文檔樹

3.5.1、修改tag的名稱和屬性

使用案例:

from bs4 import BeautifulSoupsoup = BeautifulSoup('<b class="boldest">Extremely bold</b>', "html5lib") tag = soup.b tag.name = "blockquote" print(tag) # <blockquote class="boldest">Extremely bold</blockquote> tag['class'] = 'veryBold' tag['id'] = 1 print(tag) # <blockquote class="veryBold" id="1">Extremely bold</blockquote>del tag['id'] # 刪除屬性

3.5.2、修改 .string

? ??tag的?.string?屬性賦值,就相當于用當前的標簽中的內容

from bs4 import BeautifulSoupsoup = BeautifulSoup('<b class="boldest">Extremely bold</b>', "html5lib") tag = soup.b tag.string = "replace" print(tag) # <b class="boldest">replace</b>

3.5.3、append()

? ? ?向tag中添加內容

from bs4 import BeautifulSoupsoup = BeautifulSoup('<b class="boldest">Extremely bold</b>', "html5lib") tag = soup.b tag.append(" append") print(tag) # <b class="boldest">Extremely bold append</b>

3.5.4、NavigableString() 和 .new_tag()

from bs4 import BeautifulSoup, NavigableString, Commentsoup = BeautifulSoup('<div><b class="boldest">Extremely bold</b></div>', "html5lib") tag = soup.div new_string = NavigableString('NavigableString') tag.append(new_string) print(tag) # <div><b class="boldest">Extremely bold</b>NavigableString</div>new_comment = soup.new_string("Nice to see you.", Comment) tag.append(new_comment) print(tag) # <div><b class="boldest">Extremely bold</b>NavigableString<!--Nice to see you.--></div># 添加標簽,推薦使用工廠方法new_tag new_tag = soup.new_tag("a", href="http://www.example.com") tag.append(new_tag) print(tag) # <div><b class="boldest">Extremely bold</b>NavigableString<!--Nice to see you.--><a href="http://www.example.com"></a></div>

3.5.5、insert()

? ??把元素插入到指定的位置

from bs4 import BeautifulSoupmarkup = '<a href="http://example.com/">I linked to <i>example.com</i></a>' soup = BeautifulSoup(markup,"html5lib") tag = soup.a tag.insert(1, "but did not endorse ") # 和append的區別就是.contents屬性獲取不一致 print(tag) # <a href="http://example.com/">I linked to but did not endorse <i>example.com</i></a> print(tag.contents) # ['I linked to ', 'but did not endorse ', <i>example.com</i>]

3.5.6、insert_before() 和 insert_after()

? ??當前tag或文本節點前/后插入內容

from bs4 import BeautifulSoupmarkup = '<a href="http://example.com/">I linked to</a>' soup = BeautifulSoup(markup, "html5lib") tag = soup.new_tag("i") tag.string = "Don't" soup.a.string.insert_before(tag) print(soup.a) # <a href="http://example.com/"><i>Don't</i>I linked to</a>soup.a.i.insert_after(soup.new_string(" ever ")) print(soup.a) # <a href="http://example.com/"><i>Don't</i> ever I linked to</a>

3.5.7、clear()

? ??移除當前tag的內容

from bs4 import BeautifulSoupmarkup = '<a href="http://example.com/">I linked to</a>' soup = BeautifulSoup(markup, "html5lib") tag = soup.a tag.clear() print(tag) # <a href="http://example.com/"></a>

3.5.8、extract()

? ??將當前tag移除文檔樹,并作為方法結果返回

from bs4 import BeautifulSoupmarkup = '<a href="http://example.com/">I linked to <i>example.com</i></a>' soup = BeautifulSoup(markup, "html5lib") a_tag = soup.a i_tag = soup.i.extract()print(a_tag) # <a href="http://example.com/">I linked to </a> print(i_tag) # <i>example.com</i> 我們移除的內容

3.5.9、decompose()

? ??將當前節點移除文檔樹并完全銷毀

from bs4 import BeautifulSoupmarkup = '<a href="http://example.com/">I linked to <i>example.com</i></a>' soup = BeautifulSoup(markup, "html5lib") a_tag = soup.a soup.i.decompose() print(a_tag) # <a href="http://example.com/">I linked to </a>

3.5.10、replace_with()

? ??移除文檔樹中的某段內容,并用新tag或文本節點替代它

from bs4 import BeautifulSoupmarkup = '<a href="http://example.com/">I linked to <i>example.com</i></a>' soup = BeautifulSoup(markup, "html5lib") new_tag = soup.new_tag("b") new_tag.string = "example.net" soup.a.i.replace_with(new_tag) print(soup.a) # <a href="http://example.com/">I linked to <b>example.net</b></a>

3.5.11、wrap()和unwrap()

? ??wrap()對指定的tag元素進行包裝,unwrap()移除tag內的所有tag標簽,該方法常被用來進行標記的解包

from bs4 import BeautifulSoupmarkup = '<a href="http://example.com/">I linked to <i>example.com</i></a>' soup = BeautifulSoup(markup, "html5lib") a_tag = soup.aa_tag.i.unwrap() print(a_tag) # <a href="http://example.com/">I linked to example.com</a>soup2 = BeautifulSoup("<p>I wish I was bold.</p>", "html5lib") soup2.p.string.wrap(soup2.new_tag("b")) print(soup2.p) # <p><b>I wish I was bold.</b></p>

3.6、輸出

3.6.1、格式化輸出

? ? prettify()?方法將Beautiful Soup的文檔樹格式化后以Unicode編碼輸出,每個XML/HTML標簽都獨占一行。

from bs4 import BeautifulSoupmarkup = '<a href="http://example.com/">I linked to <i>example.com</i></a>' soup = BeautifulSoup(markup, "html5lib") print(soup) # <html><head></head><body><a href="http://example.com/">I linked to <i>example.com</i></a></body></html> print(soup.prettify()) #<html># <head># </head># <body># <a href="http://example.com/"># I linked to# <i># example.com# </i># </a># </body># </html>

3.6.2、壓縮輸出

? ??如果只想得到結果字符串,不重視格式,那么可以對一個?BeautifulSoup?對象或?Tag?對象使用Python的str()?方法。

3.6.3、get_text()只輸出tag中的文本內容

? ??如果只想得到tag中包含的文本內容,那么可以調用?get_text()?方法。

from bs4 import BeautifulSoupmarkup = '<a href="http://example.com/">I linked to <i>example.com</i>點我</a>' soup = BeautifulSoup(markup, "html5lib") print(soup) # <html><head></head><body><a href="http://example.com/">I linked to <i>example.com</i></a></body></html> print(str(soup)) # <html><head></head><body><a href="http://example.com/">I linked to <i>example.com</i>點我</a></body></html> print(soup.get_text()) # I linked to example.com

4、re標準庫(模塊)

? ? BeautifulSoup庫,重html文檔中篩選我們想要的數據,但這些數據可能還有很多更細致的內容,比如,我們取到的是不是我們想要的鏈接、是不是我們需要提取的郵箱數據等等,為了更細致精確的提取數據,那么正則來了。

? ? 正則表達式(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE),是計算機科學的一個概念。正則表達式使用單個字符串來描述、匹配一系列匹配某個句法規則的字符串。在其他語言中,我們也經常會接觸到正則表達式。? ? ? ? ? ? ??

?使用案例:

import re# 創建正則對象 pat = re.compile('\d{2}') #出現2次數字的 # search 在任意位置對給定的正則表達式模式搜索第一次出現的匹配情況 s = pat.search("12abc") print(s.group()) # 12# match 從字符串起始部分對模式進行匹配 m = pat.match('1224abc') print(m.group()) # 12# search 和 match 的區別 匹配的位置不也一樣 s1 = re.search('foo', 'bfoo').group() print(s1) # foo try:m1 = re.match('foo','bfoo').group() # AttributeError except:print('匹配失敗') # 匹配失敗# 原生字符串(\B 不是以py字母結尾的) allList = ["py!", "py.", "python"] for li in allList:# re.match(正則表達式,要匹配的字符串)if re.match(r'py\B', li):print(li) # python# findall() s = "apple Apple APPLE" print(re.findall(r'apple', s)) # ['apple'] print(re.findall(r'apple', s, re.I)) # ['apple', 'Apple', 'APPLE']# sub()查找并替換 print(re.sub('a', 'A', 'abcdacdl')) # AbcdAcdl

5、實踐案例

? ? 我們以豆瓣https://movie.douban.com/top250網站為例,去爬取電影信息。

5.1、第一步使用urllib庫獲取網頁

? ? 首先,我們分析一下這個網頁的結構,是一個還算比較規則的網頁,每頁25條,一共10頁。

? ? 我們點擊第一頁:url =?https://movie.douban.com/top250?start=0&filter=

? ? 我們點擊第二頁:url =?https://movie.douban.com/top250?start=25&filter=

? ? 我們點擊第三頁:url =?https://movie.douban.com/top250?start=50&filter=

import urllib.request, urllib.error# 定義基礎url,發現規律,每頁最后變動的是start=后面的數字 baseurl = "https://movie.douban.com/top250?start="# 定義一個函數getHtmlByURL,得到指定url網頁的內容 def geturl(url):# 自定義headers(偽裝,告訴豆瓣服務器,我們是什么類型的機器,以免被反爬蟲)headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}# 利用Request類來構造自定義頭的請求req = urllib.request.Request(url, headers=headers)# 定義一個接收變量,用于接收html = ""try:# urlopen()方法的參數,發送給服務器并接收響應resp = urllib.request.urlopen(req)# urlopen()獲取頁面內容,返回的數據格式為bytes類型,需要decode()解碼,轉換成str類型html = resp.read().decode("utf-8")except urllib.error.URLError as e:if hasattr(e, "code"):print(e.code)if hasattr(e, "reason"):print(e.reason)return htmldef main():print(geturl(baseurl + "0"))if __name__ == "__main__":main()

? ? 第一步:我們已經成功獲取到了指定的網頁內容;

5.2、第二步使用BeautifulSoup和re庫解析數據

5.2.1、定位數據塊

? ? 我們發現,我們需要的數據都在<li></li>標簽中一個叫<div class="item"></div>中

import urllib.request, urllib.error from bs4 import BeautifulSoup import re # 定義基礎url,發現規律,每頁最后變動的是start=后面的數字 baseurl = "https://movie.douban.com/top250?start="# 定義一個函數getHtmlByURL,得到指定url網頁的內容 def geturl(url):# 自定義headers(偽裝,告訴豆瓣服務器,我們是什么類型的機器,以免被反爬蟲)headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}# 利用Request類來構造自定義頭的請求req = urllib.request.Request(url, headers=headers)# 定義一個接收變量,用于接收html = ""try:# urlopen()方法的參數,發送給服務器并接收響應resp = urllib.request.urlopen(req)# urlopen()獲取頁面內容,返回的數據格式為bytes類型,需要decode()解碼,轉換成str類型html = resp.read().decode("utf-8")except urllib.error.URLError as e:if hasattr(e, "code"):print(e.code)if hasattr(e, "reason"):print(e.reason)return html# 定義一個函數,并解析這個網頁 def analysisData(url):# 獲取指定網頁html = geturl(url)# 指定解析器解析html,得到BeautifulSoup對象soup = BeautifulSoup(html, "html5lib")# 定位我們的數據塊在哪for item in soup.findAll('div', class_="item"):print(item)return "" def main():print(analysisData(baseurl + "0"))if __name__ == "__main__":main()

輸出的第一個數據塊:

<div class="item"><div class="pic"><em class="">1</em><a href="https://movie.douban.com/subject/1292052/"><img alt="肖申克的救贖" class="" src="https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg" width="100"/></a></div><div class="info"><div class="hd"><a class="" href="https://movie.douban.com/subject/1292052/"><span class="title">肖申克的救贖</span><span class="title">?/?The Shawshank Redemption</span><span class="other">?/?月黑高飛(港) / 刺激1995(臺)</span></a><span class="playable">[可播放]</span></div><div class="bd"><p class="">導演: 弗蘭克·德拉邦特 Frank Darabont???主演: 蒂姆·羅賓斯 Tim Robbins /...<br/>1994?/?美國?/?犯罪 劇情</p><div class="star"><span class="rating5-t"></span><span class="rating_num" property="v:average">9.7</span><span content="10.0" property="v:best"></span><span>2390982人評價</span></div><p class="quote"><span class="inq">希望讓人自由。</span></p></div></div></div> <div class="item">

5.2.2、使用正則解析數據塊

import urllib.request, urllib.error from bs4 import BeautifulSoup import re# 定義基礎url,發現規律,每頁最后變動的是start=后面的數字 baseurl = "https://movie.douban.com/top250?start="# 定義一個函數getHtmlByURL,得到指定url網頁的內容 def geturl(url):# 自定義headers(偽裝,告訴豆瓣服務器,我們是什么類型的機器,以免被反爬蟲)headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}# 利用Request類來構造自定義頭的請求req = urllib.request.Request(url, headers=headers)# 定義一個接收變量,用于接收html = ""try:# urlopen()方法的參數,發送給服務器并接收響應resp = urllib.request.urlopen(req)# urlopen()獲取頁面內容,返回的數據格式為bytes類型,需要decode()解碼,轉換成str類型html = resp.read().decode("utf-8")except urllib.error.URLError as e:if hasattr(e, "code"):print(e.code)if hasattr(e, "reason"):print(e.reason)return html# 定義正則對象獲取指定的內容 # 提取鏈接(鏈接的格式都是<a href="開頭的) findLink = re.compile(r'<a href="(.*?)">') # 提取圖片 findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S) # re.S讓 '.' 特殊字符匹配任何字符,包括換行符; # 提取影片名稱 findTitle = re.compile(r'<span class="title">(.*)</span>') # 提取影片評分 findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>') # 提取評價人數 findJudge = re.compile(r'<span>(\d*)人評價</span>') # 提取簡介 inq = re.compile(r'<span class="inq">(.*)</span>') # 提取相關內容 findBd = re.compile(r'<p class="">(.*)</p>(.*)<div', re.S)# 定義一個函數,并解析這個網頁 def analysisData(baseurl):# 獲取指定網頁html = geturl(baseurl)# 指定解析器解析html,得到BeautifulSoup對象soup = BeautifulSoup(html, "html5lib")dataList = []# 定位我們的數據塊在哪for item in soup.find_all('div', class_="item"):# item 是 bs4.element.Tag 對象,這里將其轉換成字符串來處理item = str(item)# 定義一個列表 來存儲每一個電影解析的內容data = []# findall返回的是一個列表,這里提取鏈接link = re.findall(findLink, item)[0]data.append(link) # 添加鏈接img = re.findall(findImgSrc, item)[0]data.append(img) # 添加圖片鏈接title = re.findall(findTitle, item)# 一般都有一個中文名 一個外文名if len(title) == 2:# ['肖申克的救贖', '\xa0/\xa0The Shawshank Redemption']titlename = title[0] + title[1].replace(u'\xa0', '')else:titlename = title[0] + ""data.append(titlename) # 添加標題pf = re.findall(findRating, item)[0]data.append(pf)pjrs = re.findall(findJudge, item)[0]data.append(pjrs)# 有的可能沒有inqInfo = re.findall(inq, item)if len(inqInfo) == 0:data.append(" ")else:data.append(inqInfo[0])bd = re.findall(findBd, item)[0]# [('\n 導演: 弗蘭克·德拉邦特 Frank Darabont\xa0\xa0\xa0主演: 蒂姆·羅賓斯 Tim Robbins /...<br/>\n 1994\xa0/\xa0美國\xa0/\xa0犯罪 劇情\n ', '\n\n \n ')]bd[0].replace(u'\xa0', '').replace('<br/>', '')bd = re.sub('<\\s*b\\s*r\\s*/\\s*>', "", bd[0])bd = re.sub('(\\s+)?', '', bd)data.append(bd)dataList.append(data)return dataListdef main():print(analysisData(baseurl + "0"))if __name__ == "__main__":main()

第一頁解析結果:后面需要對analysisData稍加改造,將豆瓣Top250的10頁進行處理

[['https://movie.douban.com/subject/1292052/', 'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg', '肖申克的救贖/The Shawshank Redemption', '9.7', '2391074', '希望讓人自由。', '導演:弗蘭克·德拉邦特FrankDarabont主演:蒂姆·羅賓斯TimRobbins/...1994/美國/犯罪劇情'], ['https://movie.douban.com/subject/1291546/', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2561716440.jpg', '霸王別姬', '9.6', '1780355', '風華絕代。', '導演:陳凱歌KaigeChen主演:張國榮LeslieCheung/張豐毅FengyiZha...1993/中國大陸中國香港/劇情愛情同性'], ['https://movie.douban.com/subject/1292720/', 'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p2372307693.jpg', '阿甘正傳/Forrest Gump', '9.5', '1800723', '一部美國近現代史。', '導演:羅伯特·澤米吉斯RobertZemeckis主演:湯姆·漢克斯TomHanks/...1994/美國/劇情愛情'], ['https://movie.douban.com/subject/1295644/', 'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p511118051.jpg', '這個殺手不太冷/Léon', '9.4', '1971155', '怪蜀黍和小蘿莉不得不說的故事。', '導演:呂克·貝松LucBesson主演:讓·雷諾JeanReno/娜塔莉·波特曼...1994/法國美國/劇情動作犯罪'], ['https://movie.douban.com/subject/1292722/', 'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p457760035.jpg', '泰坦尼克號/Titanic', '9.4', '1762280', '失去的才是永恒的。 ', '導演:詹姆斯·卡梅隆JamesCameron主演:萊昂納多·迪卡普里奧Leonardo...1997/美國墨西哥澳大利亞加拿大/劇情愛情災難'], ['https://movie.douban.com/subject/1292063/', 'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p2578474613.jpg', '美麗人生/La vita è bella', '9.6', '1105760', '最美的謊言。', '導演:羅伯托·貝尼尼RobertoBenigni主演:羅伯托·貝尼尼RobertoBeni...1997/意大利/劇情喜劇愛情戰爭'], ['https://movie.douban.com/subject/1291561/', 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2557573348.jpg', '千與千尋/千と千尋の神隠し', '9.4', '1877996', '最好的宮崎駿,最好的久石讓。 ', '導演:宮崎駿HayaoMiyazaki主演:柊瑠美RumiH?ragi/入野自由Miy...2001/日本/劇情動畫奇幻'], ['https://movie.douban.com/subject/1295124/', 'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p492406163.jpg', "辛德勒的名單/Schindler's List", '9.5', '918645', '拯救一個人,就是拯救整個世界。', '導演:史蒂文·斯皮爾伯格StevenSpielberg主演:連姆·尼森LiamNeeson...1993/美國/劇情歷史戰爭'], ['https://movie.douban.com/subject/3541415/', 'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p2616355133.jpg', '盜夢空間/Inception', '9.3', '1734973', '諾蘭給了我們一場無法盜取的夢。', '導演:克里斯托弗·諾蘭ChristopherNolan主演:萊昂納多·迪卡普里奧Le...2010/美國英國/劇情科幻懸疑冒險'], ['https://movie.douban.com/subject/3011091/', 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p524964039.jpg', "忠犬八公的故事/Hachi: A Dog's Tale", '9.4', '1192778', '永遠都不能忘記你所愛的人。', '導演:萊塞·霍爾斯道姆LasseHallstr?m主演:理查·基爾RichardGer...2009/美國英國/劇情'], ['https://movie.douban.com/subject/1889243/', 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2614988097.jpg', '星際穿越/Interstellar', '9.3', '1408128', '愛是一種力量,讓我們超越時空感知它的存在。', '導演:克里斯托弗·諾蘭ChristopherNolan主演:馬修·麥康納MatthewMc...2014/美國英國加拿大/劇情科幻冒險'], ['https://movie.douban.com/subject/1292064/', 'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p479682972.jpg', '楚門的世界/The Truman Show', '9.3', '1325913', '如果再也不能見到你,祝你早安,午安,晚安。', '導演:彼得·威爾PeterWeir主演:金·凱瑞JimCarrey/勞拉·琳妮Lau...1998/美國/劇情科幻'], ['https://movie.douban.com/subject/1292001/', 'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2574551676.jpg', "海上鋼琴師/La leggenda del pianista sull'oceano", '9.3', '1409712', '每個人都要走一條自己堅定了的路,就算是粉身碎骨。 ', '導演:朱塞佩·托納多雷GiuseppeTornatore主演:蒂姆·羅斯TimRoth/...1998/意大利/劇情音樂'], ['https://movie.douban.com/subject/3793023/', 'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p579729551.jpg', '三傻大鬧寶萊塢/3 Idiots', '9.2', '1583056', '英俊版憨豆,高情商版謝耳朵。', '導演:拉庫馬·希拉尼RajkumarHirani主演:阿米爾·汗AamirKhan/卡...2009/印度/劇情喜劇愛情歌舞'], ['https://movie.douban.com/subject/2131459/', 'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p1461851991.jpg', '機器人總動員/WALL·E', '9.3', '1113357', '小瓦力,大人生。', '導演:安德魯·斯坦頓AndrewStanton主演:本·貝爾特BenBurtt/艾麗...2008/美國/科幻動畫冒險'], ['https://movie.douban.com/subject/1291549/', 'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p1910824951.jpg', '放牛班的春天/Les choristes', '9.3', '1098339', '天籟一般的童聲,是最接近上帝的存在。 ', '導演:克里斯托夫·巴拉蒂ChristopheBarratier主演:熱拉爾·朱尼奧Gé...2004/法國瑞士德國/劇情喜劇音樂'], ['https://movie.douban.com/subject/1307914/', 'https://img2.doubanio.com/view/photo/s_ratio_poster/public/p2564556863.jpg', '無間道/無間道', '9.3', '1074152', '香港電影史上永不過時的杰作。', '導演:劉偉強/麥兆輝主演:劉德華/梁朝偉/黃秋生2002/中國香港/劇情犯罪驚悚'], ['https://movie.douban.com/subject/25662329/', 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2614500649.jpg', '瘋狂動物城/Zootopia', '9.2', '1555912', '迪士尼給我們營造的烏托邦就是這樣,永遠善良勇敢,永遠出乎意料。', '導演:拜倫·霍華德ByronHoward/瑞奇·摩爾RichMoore主演:金妮弗·...2016/美國/喜劇動畫冒險'], ['https://movie.douban.com/subject/1292213/', 'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2455050536.jpg', '大話西游之大圣娶親/西遊記大結局之仙履奇緣', '9.2', '1283551', '一生所愛。', '導演:劉鎮偉JeffreyLau主演:周星馳StephenChow/吳孟達ManTatNg...1995/中國香港中國大陸/喜劇愛情奇幻古裝'], ['https://movie.douban.com/subject/5912992/', 'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p1363250216.jpg', '熔爐/???', '9.3', '778782', '我們一路奮戰不是為了改變世界,而是為了不讓世界改變我們。', '導演:黃東赫Dong-hyukHwang主演:孔侑YooGong/鄭有美Yu-miJung/...2011/韓國/劇情'], ['https://movie.douban.com/subject/1291841/', 'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p616779645.jpg', '教父/The Godfather', '9.3', '781422', '千萬不要記恨你的對手,這樣會讓你失去理智。', '導演:弗朗西斯·福特·科波拉FrancisFordCoppola主演:馬龍·白蘭度M...1972/美國/劇情犯罪'], ['https://movie.douban.com/subject/1849031/', 'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2614359276.jpg', '當幸福來敲門/The Pursuit of Happyness', '9.1', '1273152', '平民勵志片。 ', '導演:加布里爾·穆奇諾GabrieleMuccino主演:威爾·史密斯WillSmith...2006/美國/劇情傳記家庭'], ['https://movie.douban.com/subject/1291560/', 'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2540924496.jpg', '龍貓/となりのトトロ', '9.2', '1062785', '人人心中都有個龍貓,童年就永遠不會消失。', '導演:宮崎駿HayaoMiyazaki主演:日高法子NorikoHidaka/坂本千夏Ch...1988/日本/動畫奇幻冒險'], ['https://movie.douban.com/subject/3319755/', 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p501177648.jpg', '怦然心動/Flipped', '9.1', '1511459', '真正的幸福是來自內心深處。', '導演:羅伯·萊納RobReiner主演:瑪德琳·卡羅爾MadelineCarroll/卡...2010/美國/劇情喜劇愛情'], ['https://movie.douban.com/subject/1296141/', 'https://img1.doubanio.com/view/photo/s_ratio_poster/public/p1505392928.jpg', '控方證人/Witness for the Prosecution', '9.6', '378892', '比利·懷德滿分作品。', '導演:比利·懷爾德BillyWilder主演:泰隆·鮑華TyronePower/瑪琳·...1957/美國/劇情犯罪懸疑']]

5.3、將數據導出excel

import urllib.request, urllib.error from bs4 import BeautifulSoup import re import xlwt# 定義基礎url,發現規律,每頁最后變動的是start=后面的數字 baseurl = "https://movie.douban.com/top250?start="# 定義一個函數getHtmlByURL,得到指定url網頁的內容 def geturl(url):# 自定義headers(偽裝,告訴豆瓣服務器,我們是什么類型的機器,以免被反爬蟲)headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}# 利用Request類來構造自定義頭的請求req = urllib.request.Request(url, headers=headers)# 定義一個接收變量,用于接收html = ""try:# urlopen()方法的參數,發送給服務器并接收響應resp = urllib.request.urlopen(req)# urlopen()獲取頁面內容,返回的數據格式為bytes類型,需要decode()解碼,轉換成str類型html = resp.read().decode("utf-8")except urllib.error.URLError as e:if hasattr(e, "code"):print(e.code)if hasattr(e, "reason"):print(e.reason)return html# 定義正則對象獲取指定的內容 # 提取鏈接(鏈接的格式都是<a href="開頭的) findLink = re.compile(r'<a href="(.*?)">') # 提取圖片 findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S) # re.S讓 '.' 特殊字符匹配任何字符,包括換行符; # 提取影片名稱 findTitle = re.compile(r'<span class="title">(.*)</span>') # 提取影片評分 findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>') # 提取評價人數 findJudge = re.compile(r'<span>(\d*)人評價</span>') # 提取簡介 inq = re.compile(r'<span class="inq">(.*)</span>') # 提取相關內容 findBd = re.compile(r'<p class="">(.*)</p>(.*)<div', re.S)# 定義接收10頁的列表 dataList = []# 定義一個函數,并解析這個網頁 def analysisData(baseurl):# 獲取指定網頁for i in range(0, 10): # 獲取網頁選項的函數,10次url = baseurl + str(i * 25)html = geturl(url)# 指定解析器解析html,得到BeautifulSoup對象soup = BeautifulSoup(html, "html5lib")# 定位我們的數據塊在哪for item in soup.find_all('div', class_="item"):# item 是 bs4.element.Tag 對象,這里將其轉換成字符串來處理item = str(item)# 定義一個列表 來存儲每一個電影解析的內容data = []# findall返回的是一個列表,這里提取鏈接link = re.findall(findLink, item)[0]data.append(link) # 添加鏈接img = re.findall(findImgSrc, item)[0]data.append(img) # 添加圖片鏈接title = re.findall(findTitle, item)# 一般都有一個中文名 一個外文名if len(title) == 2:# ['肖申克的救贖', '\xa0/\xa0The Shawshank Redemption']titlename = title[0] + title[1].replace(u'\xa0', '')else:titlename = title[0] + ""data.append(titlename) # 添加標題pf = re.findall(findRating, item)[0]data.append(pf)pjrs = re.findall(findJudge, item)[0]data.append(pjrs)inqInfo = re.findall(inq, item)if len(inqInfo) == 0:data.append(" ")else:data.append(inqInfo[0])bd = re.findall(findBd, item)[0]# [('\n 導演: 弗蘭克·德拉邦特 Frank Darabont\xa0\xa0\xa0主演: 蒂姆·羅賓斯 Tim Robbins /...<br/>\n 1994\xa0/\xa0美國\xa0/\xa0犯罪 劇情\n ', '\n\n \n ')]bd[0].replace(u'\xa0', '').replace('<br/>', '')bd = re.sub('<\\s*b\\s*r\\s*/\\s*>', "", bd[0])bd = re.sub('(\\s+)?', '', bd)data.append(bd)dataList.append(data)return dataListdef main():analysisData(baseurl)savepath = "C:\\Users\\Administrator\\Desktop\\python_3.8.5\\豆瓣250.xls"book = xlwt.Workbook(encoding="utf-8", style_compression=0) # 創建Workbook對象sheet = book.add_sheet("豆瓣電影Top250", cell_overwrite_ok=True) # 創建工作表col = ("電影詳情鏈接", "圖片鏈接", "電影中/外文名", "評分", "評論人數", "概況", "相關信息")print(len(dataList))for i in range(0, 7):sheet.write(0, i, col[i])for i in range(0, 250):print('正在保存第'+str((i+1))+'條')data = dataList[i]for j in range(len(data)):sheet.write(i + 1, j, data[j])book.save(savepath)if __name__ == "__main__":main()

最終效果:

總結

以上是生活随笔為你收集整理的python爬虫详解的全部內容,希望文章能夠幫你解決所遇到的問題。

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

亚洲色视频| 国产99久久久精品 | 国产美女免费看 | av不卡免费看 | 午夜精品一区二区三区在线视频 | 激情综合五月婷婷 | 日韩亚洲欧美中文字幕 | 韩日电影在线观看 | 福利视频入口 | 奇米网777 | 亚洲精品日韩在线观看 | 人人网av | 99热最新精品 | 国产视频中文字幕 | 色就是色综合 | 婷婷精品国产一区二区三区日韩 | 国产99久久九九精品免费 | 国产九色91 | 久草视频播放 | 欧美性大胆 | 国产黄a三级 | 超碰成人av | 久久精品99国产国产精 | 精品美女在线视频 | 视频直播国产精品 | 91精品国产自产91精品 | 国产成人精品电影久久久 | 色综合天天色综合 | 欧美男同网站 | 日韩欧美专区 | 激情综合五月婷婷 | 国产91综合一区在线观看 | 97超碰国产在线 | 亚洲视频久久久久 | 99久久精品国产网站 | 久久精品这里热有精品 | 中文字幕免费高清在线观看 | 免费在线成人av | 久久影院午夜论 | 日韩中字在线观看 | 黄色三级免费看 | 欧美日韩久久不卡 | 九九九热精品免费视频观看网站 | 日日狠狠| 亚洲91精品 | 欧美 激情在线 | www夜夜操 | 日韩午夜电影网 | 国产又粗又硬又长又爽的视频 | 在线观看一区 | 福利视频第一页 | 韩国av免费 | 亚洲免费av在线播放 | www.黄色在线 | 美女精品国产 | 最新精品视频在线 | 国产精品成人品 | 欧美激情综合五月 | 91视频高清完整版 | 免费在线国产 | 97在线免费观看视频 | 日韩成人不卡 | 成人午夜久久 | 激情欧美在线观看 | 欧美日韩精品国产 | 制服丝袜在线 | 久久69精品久久久久久久电影好 | 免费观看久久 | 亚洲综合成人av | 婷婷伊人综合 | 国产精品高清免费在线观看 | 日韩在线观看视频网站 | 欧美精品一二 | 国产美女免费看 | 国产精品一区二区三区免费视频 | 精品嫩模福利一区二区蜜臀 | 欧美日韩视频在线播放 | 欧美色精品天天在线观看视频 | www.com在线观看 | 欧美一区二区精美视频 | 99久久这里只有精品 | 五月天久久久 | 激情综合中文娱乐网 | 天天综合网 天天 | 国产成人一区二区三区在线观看 | 国产黄色免费看 | 青青河边草观看完整版高清 | 黄色av电影在线 | 怡红院成人在线 | 在线看av网址 | 精品一区二区三区在线播放 | 国产精品美女久久久久久久久久久 | 亚洲精品国产精品99久久 | 天天爽天天做 | 毛片在线网 | 久青草视频在线观看 | 成人中心免费视频 | 日本中文字幕电影在线免费观看 | 久人人 | 91在线观看欧美日韩 | 黄污视频网站大全 | 国产精久久久久久妇女av | 国产精品一区二区在线免费观看 | 欧美成人中文字幕 | 麻豆视频成人 | 丁香五月亚洲综合在线 | 韩国精品福利一区二区三区 | 免费看三级黄色片 | 成人欧美日韩国产 | 国产精品美女久久久 | 亚洲精品网站在线 | 婷婷丁香在线视频 | 亚洲欧美日韩精品一区二区 | 久久久久女人精品毛片九一 | 亚洲国产欧洲综合997久久, | 午夜性色| 中文字幕制服丝袜av久久 | 天堂网一区二区三区 | 一区二区精品在线 | 国产va饥渴难耐女保洁员在线观看 | 久久色中文字幕 | 91精品啪在线观看国产 | 欧美一区中文字幕 | 色综合久久悠悠 | 91精品一区二区三区蜜桃 | av看片网址 | 久久久亚洲麻豆日韩精品一区三区 | 日韩欧美视频在线播放 | 在线精品亚洲一区二区 | 免费观看国产精品 | 亚洲视频 中文字幕 | 黄色片视频在线观看 | 三级av在线 | 国产精品18久久久久久久久 | 欧美成人h版在线观看 | 99国产成+人+综合+亚洲 欧美 | 精品国产欧美 | 99精品在线观看 | 久久激情电影 | 午夜av在线免费 | 久久久久久久久久久免费 | 超碰97国产精品人人cao | 99热精品免费观看 | 在线91av | 国产精品入口a级 | 国产片免费在线观看视频 | 亚洲综合欧美精品电影 | 欧美黑人xxxx猛性大交 | 久久久久99999 | 不卡电影免费在线播放一区 | 人人盈棋牌 | 国产在线污 | 欧美精品一区二区三区一线天视频 | 精品欧美一区二区精品久久 | 在线看成人 | 欧美最新大片在线看 | 91成人小视频 | 日韩精品你懂的 | 日日爽 | 91黄色成人 | 99精品国产兔费观看久久99 | 日本高清久久久 | 美女黄濒 | www狠狠 | 国产三级视频在线 | 91视频传媒 | 欧美性脚交| 欧美一级免费 | av在线网站大全 | 久久国语 | 国产视频不卡 | 欧美视频99 | 精品久久免费 | 久久国产色 | 亚洲电影黄色 | 欧美激情第十页 | 中文字幕久久久精品 | 欧美日韩视频 | 国产精品一区二区果冻传媒 | 中文字幕 国产专区 | 欧美国产日韩一区二区三区 | 免费黄色激情视频 | 91精品小视频 | 天天操比| 精品国产乱码久久久久久天美 | 欧美精品在线观看免费 | 人人爽人人爽人人爽学生一级 | 草久久久久久久 | 午夜久久久久久久久久影院 | 久久国产经典 | 日韩精品在线观看av | 亚洲国产电影在线观看 | 91超碰在线播放 | 国产成人久久av免费高清密臂 | 精品视频国产 | 国产99在线播放 | 国产精品丝袜久久久久久久不卡 | 中文字幕亚洲精品日韩 | 日韩videos高潮hd| 97国产大学生情侣酒店的特点 | 中文字幕在线观看第一区 | 欧美国产日韩在线视频 | 国产精品精品国产婷婷这里av | 香蕉影视在线观看 | 波多野结衣一区二区三区中文字幕 | 亚洲精品久久视频 | 天天色综合三 | 亚洲国产精品电影在线观看 | 午夜影视av | 亚洲美女在线国产 | 亚洲视频精品 | 欧美综合色 | 91综合色| 日韩黄色在线电影 | 在线观看精品一区 | 特级aaa毛片 | 国产麻豆视频网站 | 久久综合网色—综合色88 | 一区电影 | 国产男女免费完整视频 | 国产探花视频在线播放 | 亚洲精品国产视频 | 99久久精品免费 | 97在线观看免费观看 | 亚洲欧美视屏 | 亚洲精品久久久久久久不卡四虎 | 综合色中色 | 91中文字幕在线 | 99精品视频在线观看视频 | 00av视频| 波多野结衣精品在线 | 欧美在线观看视频一区二区三区 | 91麻豆精品国产91久久久无限制版 | 国产精品美女久久久久久免费 | 一区电影 | 欧美最新大片在线看 | 91免费版在线| 日本一区二区三区免费观看 | adc在线观看 | 一区二区三区四区精品视频 | 91日韩精品视频 | 国产日韩一区在线 | 性色av免费看 | 精品一二 | 综合色婷婷 | 欧美一级视频免费 | 欧美一区二区免费在线观看 | 欧美精品一二 | 色狠狠综合 | 久久久久久黄色 | 国产成人黄色在线 | 日本在线观看一区二区三区 | 亚洲综合成人av | 久久久天天操 | 精品久久久久亚洲 | 亚洲一区二区高潮无套美女 | 91香蕉嫩草 | 成人一区二区三区中文字幕 | 亚洲国产视频在线 | 免费成人短视频 | www.色com | 日韩av一区二区三区四区 | 在线视频久 | 激情文学丁香 | 国产一级在线观看视频 | 久久国产精品影片 | 亚洲三级精品 | 国产经典 欧美精品 | 久久久国产一区二区 | 91成人在线网站 | 久久电影中文字幕视频 | 国产精品久久久久一区二区 | 国产色a在线观看 | 日本护士撒尿xxxx18 | 99精品在线观看视频 | 久久久国产一区二区三区 | 天天干天天拍天天操 | 日日爽日日操 | 国产视频资源在线观看 | 成年人在线观看视频免费 | 草久视频在线观看 | 亚洲精品婷婷 | 日韩一二三在线 | .精品久久久麻豆国产精品 亚洲va欧美 | 日韩色在线 | 99久久婷婷国产精品综合 | 国产成人久久av977小说 | 免费av在线网站 | 天天爱天天爽 | 天天干,天天插 | 国产一级电影 | 亚洲精品国产欧美在线观看 | 国产日本三级 | 国产精品久久久精品 | 97碰碰碰| 婷婷丁香狠狠爱 | 黄色av影视 | 国产永久免费观看 | 91在线视频免费 | 99久久精品国产亚洲 | 日韩二区在线 | 999亚洲国产996395 | 天天视频亚洲 | 中中文字幕av| 黄色av在 | 成人av网站在线 | 亚洲精品ww | 国产成人一区二区三区影院在线 | 免费电影播放 | 成人免费在线观看电影 | 99精品影视 | 丁香婷婷色月天 | 在线观看免费成人av | 国产精品久久久久久久久久久久午夜 | 欧美一级爽 | 黄色一级性片 | 麻豆传媒视频在线 | 日韩中文字幕在线不卡 | 日本免费一二三区 | 1024在线看片 | 成人免费视频网址 | 欧美日韩国产精品一区 | 中文在线免费看视频 | 精品伦理一区二区三区 | 国产精品aⅴ | 婷婷福利影院 | 久久99精品热在线观看 | 国产91精品一区二区麻豆网站 | 婷婷国产一区二区三区 | 国产成人精品午夜在线播放 | 日韩欧美视频一区二区 | av超碰在线观看 | 天天射综合网站 | 少妇做爰k8经典 | 国产精品成人国产乱一区 | 久久99热精品这里久久精品 | 在线中文字幕一区二区 | 超碰在线色| 亚洲波多野结衣 | 国产人成在线视频 | 天天曰天天 | 久久国产精品99国产精 | 97成人资源站 | 91久久丝袜国产露脸动漫 | 日韩精品综合在线 | 久久精品欧美 | 久久久国产一区二区三区四区小说 | 嫩草91影院| 激情网五月 | 日日操天天操狠狠操 | 日韩欧美精品一区二区 | 一区二区三区在线电影 | 国产精品av在线免费观看 | 在线观看黄网 | 国产在线一区观看 | 日韩在线观看的 | 日本黄色免费在线 | 9999国产精品 | 日日干夜夜操视频 | 久久另类视频 | 日韩成人高清在线 | 五月天激情综合 | 黄色动态图xx | 中文字幕丝袜 | 999久久a精品合区久久久 | 在线免费国产 | 亚洲在线高清 | 91九色网站 | 91网站免费观看 | 亚洲国产精彩中文乱码av | 国产亚洲精品免费 | 久久精品视频网址 | av福利网址导航大全 | 久久尤物电影视频在线观看 | 日日夜夜天天综合 | 久久草草热国产精品直播 | 激情网站网址 | 国产一级黄色电影 | 一区二区三区免费看 | 日免费视频 | 亚洲综合在线播放 | 国产激情小视频在线观看 | 国产精品12 | 国产在线色 | 国内精品久久久久国产 | 欧美精品在线视频观看 | 999久久久久久| 精品免费国产一区二区三区四区 | 久久久www成人免费精品张筱雨 | bayu135国产精品视频 | 激情视频综合网 | 91漂亮少妇露脸在线播放 | 精品久久久久久亚洲 | 精品国产一区二区三区久久久 | 国产精品一区电影 | 激情视频一区二区三区 | 成人在线免费视频观看 | 天天做日日做天天爽视频免费 | 久久久精品国产免费观看同学 | 亚洲国产精品久久 | 91免费看片黄 | 国产精品一区二区白浆 | 色婷婷综合久久久久中文字幕1 | 国产黄色片在线免费观看 | 日韩三级av| 欧美一级性视频 | 91久久精品日日躁夜夜躁国产 | 久久久久国产成人精品亚洲午夜 | 丁香婷婷激情 | 日本在线视频一区二区三区 | 福利电影一区二区 | 国产黄色在线看 | 伊人手机在线 | 亚洲开心激情 | 欧美巨大荫蒂茸毛毛人妖 | 久久国产一区 | 亚洲电影影音先锋 | 97天堂| 久草在线在线精品观看 | 视频1区2区 | 国产成a人亚洲精v品在线观看 | 国产美女精品 | 97超碰成人在线 | 亚洲在线黄色 | 在线看毛片网站 | 美女一级毛片视频 | a视频免费看 | 国产精品一区二区在线观看 | 亚洲成人资源在线 | 国产精品美女久久久久久免费 | 日韩久久网站 | 国产精品久久久久久99 | 四虎免费在线观看 | 中文字幕av在线不卡 | www免费网站在线观看 | 日韩精品视频免费专区在线播放 | 久久免费电影网 | 久久久伊人网 | 欧美一级激情 | www.天天成人国产电影 | 日韩理论影院 | 在线观av | 国产精品高潮在线观看 | 日本xxxxav| 在线播放日韩av | 色播激情五月 | 欧美电影在线观看 | 91在线精品观看 | 俺要去色综合狠狠 | 久久久久久毛片精品免费不卡 | 久久影院中文字幕 | 色com网 | 9在线观看免费高清完整 | 999视频在线播放 | 国产精品3 | 91麻豆免费视频 | 超碰在线cao | 一区二区影院 | 91精品国产福利 | aaaaaa毛片| 久久男人中文字幕资源站 | 精品国产成人av | 99精品热视频 | 精品久久久久久久久亚洲 | 亚洲日本韩国一区二区 | 在线观看亚洲免费视频 | 国产精品av免费在线观看 | 一区二区 不卡 | 成人在线观看免费视频 | 国产福利不卡视频 | 黄av免费 | av在线免费在线 | 欧美亚洲成人免费 | 九九亚洲视频 | 久久久国产影视 | 欧美成天堂网地址 | 久久99国产一区二区三区 | 在线小视频你懂得 | 毛片随便看 | 国产高清在线a视频大全 | 国产精品一区二区三区免费视频 | 国产精品久久久久久久久搜平片 | 麻豆91网站 | 日韩av线观看 | 色综合天天狠天天透天天伊人 | 99热精品免费观看 | 国产99久久久欧美黑人 | 中文字幕av在线免费 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 视频一区亚洲 | 九九热在线精品 | 国产xxxx性hd极品 | 99在线看| 超碰日韩 | 在线成人欧美 | 一级黄色av | 婷婷六月久久 | 美女福利视频在线 | www.av在线播放 | 波多野结衣在线观看一区 | 在线免费视频 你懂得 | 免费国产在线视频 | 免费视频国产 | 在线视频手机国产 | 国内久久精品 | 国内精品小视频 | 国产丝袜| 国产精品福利在线 | 亚洲精品三级 | 天天爱天天操 | 国产精品欧美一区二区 | 在线免费色视频 | 91大神在线观看视频 | 久久精品视频99 | 91九色视频国产 | 蜜臀av一区 | 欧美精品一级视频 | av片在线观看免费 | av在线网站观看 | 久久精品日本啪啪涩涩 | 国产高清免费av | 91成人精品一区在线播放 | 亚洲精品国偷自产在线99热 | 久久无码精品一区二区三区 | 国产96在线 | 日韩动态视频 | 欧美日韩一级久久久久久免费看 | 欧美日韩精品在线视频 | 草久视频在线观看 | 久久97久久97精品免视看 | 天天色视频 | 欧美夫妻性生活电影 | 久草在线资源免费 | 狠狠干美女 | 九九视频网站 | 欧美国产日韩一区二区三区 | 日韩中文字幕视频在线 | 色网站在线免费观看 | 五月天婷婷丁香花 | 亚州精品一二三区 | 在线亚洲观看 | 久久久99精品免费观看 | 欧美亚洲三级 | www.人人草| 日韩免费电影 | 六月丁香婷婷久久 | 欧美国产精品久久久久久免费 | 在线天堂中文www视软件 | 午夜三级福利 | 激情婷婷六月 | 91麻豆国产福利在线观看 | 99视频99| 亚洲精品看片 | 国产一区二区不卡在线 | av中文字幕在线免费观看 | 91精品对白一区国产伦 | 中文视频在线 | 国产高清视频在线 | 欧美性色黄 | 免费高清男女打扑克视频 | 免费亚洲精品视频 | 九九热精品视频在线播放 | 午夜精品电影一区二区在线 | 久久精品亚洲精品国产欧美 | 国产黄色在线网站 | 国产精品美女 | 三级黄色免费片 | 久久夜靖品 | 99久久夜色精品国产亚洲 | 国产日产欧美在线观看 | 最新久久免费视频 | 激情视频二区 | 91精品一| a级黄色片视频 | 2018亚洲男人天堂 | 超碰在线观看av.com | 色永久免费视频 | 97视频在线观看免费 | 成人在线小视频 | 婷婷精品国产一区二区三区日韩 | 久草视频免费 | 久草在线观看视频免费 | 久久黄页 | 国产精品网址在线观看 | 亚洲视频精品在线 | 午夜视频一区二区三区 | 在线韩国电影免费观影完整版 | 伊人看片 | 免费黄a| 亚洲麻豆精品 | 午夜精品福利一区二区 | 亚洲视频电影在线 | .精品久久久麻豆国产精品 亚洲va欧美 | 97国产大学生情侣酒店的特点 | av综合站| 麻豆国产露脸在线观看 | 国产露脸91国语对白 | 97在线视频观看 | 国产精品精品久久久久久 | 青草草在线 | 狠狠夜夜 | 丁香久久 | 久久精品国产精品 | av在线小说| 国产精品日韩久久久久 | av在线播放国产 | 久久视频免费在线 | 天天射网站 | 在线电影日韩 | 亚洲综合色视频 | 天天插天天干 | 亚洲jizzjizz日本少妇 | 国产精品精品久久久久久 | 中文字幕在线播放第一页 | 在线a人片免费观看视频 | 色综合中文字幕 | 麻豆va一区二区三区久久浪 | 欧美日韩免费一区 | 久久久男人的天堂 | 国产精品18久久久久久久久久久久 | 国产在线视频一区二区 | 在线免费观看麻豆视频 | 操操操操网 | 欧美综合久久 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 亚州国产精品久久久 | 黄色一级大片在线免费看国产一 | 五月婷色 | 久久免费国产 | 亚洲成av人片在线观看www | 免费a级大片 | 91精品在线麻豆 | 免费看片黄色 | 久久综合综合久久综合 | 日本视频精品 | 久久免费视频4 | 国产亚洲精品久久久久久移动网络 | 黄色特一级片 | 成人av电影免费在线播放 | 国产不卡一 | 成人影片免费 | 成人app在线播放 | 亚洲国产伊人 | 日韩免费福利 | 日韩视频免费观看高清 | 亚洲免费永久精品国产 | 久草在线观看视频免费 | 九九视频精品免费 | 国产亚洲精品精品精品 | 国产 在线 日韩 | 中文伊人 | 免费在线观看日韩 | 亚在线播放中文视频 | 亚洲成人av在线电影 | 久热电影| 日日躁天天躁 | 成人国产精品免费观看 | 久久久久久久久久久电影 | 中午字幕在线观看 | 亚洲精品av中文字幕在线在线 | 黄色网www | 日本高清免费中文字幕 | 国产视频日韩视频欧美视频 | 久久精品视频网 | 免费av网站观看 | 欧美了一区在线观看 | www日韩在线观看 | 久久超级碰视频 | 国内视频在线 | 国产精品女人网站 | 成人h电影| 久久99亚洲网美利坚合众国 | 国产精品毛片一区二区 | 国产福利一区二区在线 | 亚洲砖区区免费 | 色综合天天天天做夜夜夜夜做 | 激情久久小说 | 日韩av免费在线电影 | 在线观看 国产 | 2019免费中文字幕 | 国产成人精品999 | 国产精品不卡一区 | 一区二区三区电影大全 | 天天操天天弄 | av福利超碰网站 | 久久综合九色综合欧美就去吻 | 丁香久久 | 国产精品一区二区在线播放 | 日韩欧美观看 | 欧美激情综合色 | 国产精品11 | 亚洲精品久久久久久久不卡四虎 | 亚洲国产精品va在线看黑人动漫 | 国产一区二区在线免费 | 久久精品资源 | av综合站| 国产精品亚洲精品 | 成人h视频 | 干天天| 九九久久久久久久久激情 | 久久免费美女视频 | 日韩激情免费视频 | 97国产在线视频 | 天天草天天干天天射 | 欧美激情亚洲综合 | 91麻豆精品国产自产在线游戏 | 午夜精品在线看 | 亚洲精品99久久久久中文字幕 | 欧美国产日韩在线观看 | 久久私人影院 | 最新av网站在线观看 | 久久精品免视看 | 婷婷激情综合网 | 日韩在线中文字幕 | 黄色影院在线播放 | 国产精品色在线 | 精品一区二区在线免费观看 | 日韩精品免费一区二区 | 99re热精品视频| 日本美女xx | 国产在线观看高清视频 | 日韩在线观看中文 | 色综合天天综合网国产成人网 | 色99久久| www毛片com| 在线观看中文字幕 | av一本久道久久波多野结衣 | www黄色av| 欧美日韩18 | 欧美韩国在线 | 在线播放 日韩专区 | 亚洲一区二区三区在线看 | 国产精品美女www爽爽爽视频 | 爱爱一区 | 国产精品字幕 | 亚洲视频久久久久 | 久久高清片 | 欧美另类重口 | 国产精品视频你懂的 | 成人h视频在线播放 | 91热视频| 狠狠网亚洲精品 | 精品成人久久 | 亚洲在线不卡 | 免费在线观看av的网站 | 日本久久片 | 九九热免费在线观看 | av观看在线观看 | www免费网站在线观看 | 美女视频a美女大全免费下载蜜臀 | 国内精品久久久久久久影视简单 | 99r在线| 亚洲欧洲精品一区二区精品久久久 | 亚洲影院天堂 | 国产黄色片免费看 | 69精品久久 | 国产精品女同一区二区三区久久夜 | 国产一区二区不卡视频 | 韩国av一区二区三区 | 激情五月婷婷综合网 | 日韩丝袜在线观看 | 国产一级视频在线免费观看 | 欧美在线观看视频一区二区 | 久久久黄色免费网站 | 亚洲性少妇性猛交wwww乱大交 | 91视频久久久久久 | 在线观看完整版 | 911久久香蕉国产线看观看 | 一本—道久久a久久精品蜜桃 | 一区二区三区高清在线 | 天天草天天色 | 欧美日本中文字幕 | 日本视频精品 | 九九在线视频免费观看 | 亚洲天天干 | 亚洲精选99 | 狂野欧美激情性xxxx欧美 | 97人人模人人爽人人喊中文字 | 极品久久久久 | 久久国产剧场电影 | 色五月激情五月 | 国产精品videoxxxx | 色 免费观看 | 欧美a级在线免费观看 | 久草国产视频 | 国产a级精品 | 久久久久久久久久久影视 | 亚洲精品在线观看的 | 日韩av资源在线观看 | 99免费视频 | 日韩国产在线观看 | av一级片网站 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 爱爱一区 | 丁香花五月 | 丝袜少妇在线 | 在线观看黄网 | 丁香婷五月 | 久久在线播放 | 国产在线观看免费观看 | 中文字幕乱偷在线 | 国产高清免费 | 久久69精品| 成人蜜桃 | 一个色综合网站 | 日韩av有码在线 | 国产精品一区二区三区久久久 | 黄色网在线播放 | 夜夜躁狠狠躁 | 久久国产麻豆 | 人人讲 | 国产精品 日本 | 成人一区二区三区在线 | 亚洲3级| 成人激情开心网 | 亚洲国产精品人久久电影 | 精品一区 精品二区 | 国产精品 美女 | 亚洲精品国 | 日韩欧美视频免费观看 | 不卡中文字幕在线 | 四虎永久国产精品 | 天天干天天拍天天操天天拍 | 日日爽夜夜爽 | 天天草综合网 | 天天躁日日躁狠狠 | av在线专区 | 久久66热这里只有精品 | 精品久久久久久亚洲综合网站 | 精品国产_亚洲人成在线 | a色视频| 欧美性直播 | 成人va天堂 | 久久视频在线观看中文字幕 | 蜜桃视频在线观看一区 | 欧美日韩精品在线观看视频 | 激情xxxx | 精品久久五月天 | 天天色天天射天天操 | 国产中年夫妇高潮精品视频 | 色婷婷一 | 伊人色**天天综合婷婷 | 免费日韩三级 | 国产精品视频大全 | 久久综合操 | 中文字幕在线免费看 | 久久观看最新视频 | 国产视频在线观看一区 | 国产成人精品一区二区三区福利 | 91成人蝌蚪 | 日韩网站在线播放 | 久久激情五月激情 | 色妞色视频一区二区三区四区 | 青青河边草免费观看 | www.五月天婷婷 | 日本狠狠色| 国产精品美女久久久久久 | 久久免费a | 丝袜美腿一区 | 91精品一区二区三区久久久久久 | 夜夜骑天天操 | 中文字幕在线影院 | 日本久久电影网 | 97超碰国产精品女人人人爽 | 国产色秀视频 | 欧美成人一二区 | 欧美日韩另类视频 | 在线免费观看国产精品 | 日韩精品视频免费在线观看 | 欧美伦理电影一区二区 | 成人91免费视频 | 黄色在线视频网址 | 99热九九这里只有精品10 | 超碰人人在线观看 | 欧美精品一区二区在线观看 | 国产99久久精品一区二区300 | 国产不卡免费 | 最新91在线视频 | 亚洲第一中文字幕 | 欧美日韩中文在线视频 | 欧美一区三区四区 | 91精品国产91久久久久福利 | 国产在线观看免费av | 黄色三级免费看 | 亚洲国产免费看 | 久久在视频 | 午夜性色 | 国产99久久九九精品免费 | av电影中文 | 成年人黄色大片在线 | 欧美日韩中文字幕在线视频 | 国产精品高潮在线观看 | 黄色福利视频网站 | 亚洲人成精品久久久久 | 久久精品视频日本 | 91色一区二区三区 | 69视频永久免费观看 | 成人91在线| 91麻豆国产福利在线观看 | 国产黄色大片 | 人人爽人人搞 | 免费黄av| 西西www444 | av电影免费在线看 | 色欧美88888久久久久久影院 | 久久午夜电影网 | 久久久久久久18 | 特级毛片在线 | 亚洲一级片在线观看 | 最新中文在线视频 | 91在线看| 精品久久久久久久久久久久久久久久久久 | 久久精品精品电影网 | 欧美xxxxx在线视频 | av电影免费| 少妇bbw撒尿 | 激情婷婷欧美 | 精产嫩模国品一二三区 | 91一区二区三区在线观看 | 亚洲黄色免费网站 | 99久热在线精品视频观看 | www在线免费观看 | 亚洲va男人天堂 | 视频91在线 | 狠狠干夜夜 | 久久久久免费电影 | 亚洲国产精品成人va在线观看 | 播五月综合 | 亚洲综合视频在线播放 | 国产精品女同一区二区三区久久夜 | 国产精品毛片久久久久久久 | 精品999在线观看 | 欧美日韩在线观看一区二区 | 亚洲欧洲精品视频 | 91人人视频在线观看 | 97国产视频 | 久久在线免费视频 | 亚洲综合视频在线观看 | 日韩欧美精品在线 | 欧美成人在线免费观看 | 亚洲永久字幕 | 麻花传媒mv免费观看 | 日韩精品久久久久久久电影竹菊 | 久久99亚洲热视 | 日b黄色片 | 日本大尺码专区mv | 久久福利电影 | 999男人的天堂| 亚洲一二三久久 | 国产精品美女毛片真酒店 | 日本在线免费看 | 精品爱爱| 黄色免费大片 | 97国产视频| 国产精品欧美激情在线观看 | www.夜夜草| 91网址在线观看 | 亚洲视频免费在线观看 | 在线成人看片 | 97精品免费视频 | av线上免费观看 | 亚色视频在线观看 | bbbbb女女女女女bbbbb国产 | 欧美一级激情 | 久草精品在线观看 | 免费观看一级 | 一本到视频在线观看 | 91丝袜美腿| 免费色视频在线 | 久久精品91久久久久久再现 | 国产91精品看黄网站 | 国产午夜精品久久久久久久久久 | 国产精品九色 | 国产精品一区在线播放 | 国产精品久久久久av福利动漫 | 一区 二区电影免费在线观看 | 国产精品淫 | 黄av免费在线观看 | 九九精品毛片 | 91九色在线观看 | 国产亚洲精品v | 亚洲综合视频网 | 欧美精品一区二区蜜臀亚洲 | 国产精品视频永久免费播放 | 成人小视频在线免费观看 | 中文字幕在线视频第一页 | 日狠狠| 久久久久久久久久久高潮一区二区 | 久久精品日产第一区二区三区乱码 | 69视频国产 | 一区二区三区四区在线免费观看 | 国产免费一区二区三区最新6 | 亚洲视频在线视频 | 在线精品亚洲 | 国产精品久久久久影院 | 欧美日韩一区二区视频在线观看 | www.99av| 九九精品毛片 |