Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲国产日韩综合久久精品,韩国三级合集hd合集,亚洲精品视频在线播放

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          爬蟲系列(四):HTML文本解析庫BeautifulSoup

          源:Python之禪 作者:劉志軍

          題圖:@Miguel Mateo

          系列文章的第3篇介紹了網絡請求庫神器 Requests ,請求把數據返回來之后就要提取目標數據,不同的網站返回的內容通常有多種不同的格式,一種是 json 格式,這類數據對開發者來說最友好。另一種 XML 格式的,還有一種最常見格式的是 HTML 文檔,今天就來講講如何從 HTML 中提取出感興趣的數據

          直接字符串處理?自己寫個 HTML 解析器來解析嗎?還是用正則表達式?這些都不是最好的辦法,好在,Python 社區在這方面早就有了很成熟的方案,BeautifulSoup 就是這一類問題的克星,它專注于 HTML 文檔操作。

          BeautifulSoup 是一個用于解析 HTML 文檔的 Python 庫,通過 BeautifulSoup,你只需要用很少的代碼就可以提取出 HTML 中任何感興趣的內容,此外,它還有一定的 HTML 容錯能力,對于一個格式不完整的HTML 文檔,它也可以正確處理。

          安裝 BeautifulSoup

          pip install beautifulsoup4

          BeautifulSoup3 被官方放棄維護,你要下載最新的版本 BeautifulSoup4。

          HTML 標簽

          學習 BeautifulSoup4 前有必要先對 HTML 文檔有一個基本認識,如下代碼,HTML 是一個樹形組織結構。

          <html><head><title>hello, world</title></head><body><h1>BeautifulSoup</h1><p>如何使用BeautifulSoup</p><body></html>
          • 它由很多標簽(Tag)組成,比如 html、head、title等等都是標簽

          • 一個標簽對構成一個節點,比如 <html>...</html>是一個根節點

          • 節點之間存在某種關系,比如 h1 和 p 互為鄰居,他們是相鄰的兄弟(sibling)節點

          • h1 是 body 的直接子(children)節點,還是 html 的子孫(descendants)節點

          • body 是 p 的父(parent)節點,html 是 p 的祖輩(parents)節點

          • 嵌套在標簽之間的字符串是該節點下的一個特殊子節點,比如 “hello, world” 也是一個節點,只不過沒名字。

          使用 BeautifulSoup

          構建一個 BeautifulSoup 對象需要兩個參數,第一個參數是將要解析的 HTML 文本字符串,第二個參數告訴 BeautifulSoup 使用哪個解析器來解析 HTML。

          解析器負責把 HTML 解析成相關的對象,而 BeautifulSoup 負責操作數據(增刪改查)。“html.parser” 是 Python 內置的解析器,“lxml” 則是一個基于c語言開發的解析器,它的執行速度更快,不過它需要額外安裝

          通過 BeautifulSoup 對象可以定位到 HTML 中的任何一個標簽節點。

          from bs4 import BeautifulSouptext = """<html><head><title >hello, world</title></head><body><h1>BeautifulSoup</h1><p class="bold">如何使用BeautifulSoup</p><p class="big" id="key1"> 第二個p標簽</p><a soup = BeautifulSoup(text, "html.parser")# title 標簽>>> soup.title<title>hello, world</title># p 標簽>>> soup.p<p class="bold">\u5982\u4f55\u4f7f\u7528BeautifulSoup</p># p 標簽的內容>>> soup.p.stringu'\u5982\u4f55\u4f7f\u7528BeautifulSoup'

          BeatifulSoup 將 HTML 抽象成為 4 類主要的數據類型,分別是Tag , NavigableString , BeautifulSoup,Comment 。每個標簽節點就是一個Tag對象,NavigableString 對象一般是包裹在Tag對象中的字符串,BeautifulSoup 對象代表整個 HTML 文檔。例如:

          >>> type(soup)<class 'bs4.BeautifulSoup'>>>> type(soup.h1)<class 'bs4.element.Tag'>>>> type(soup.p.string)<class 'bs4.element.NavigableString'>

          Tag

          每個 Tag 都有一個名字,它對應 HTML 的標簽名稱。

          >>> soup.h1.nameu'h1'>>> soup.p.nameu'p'

          標簽還可以有屬性,屬性的訪問方式和字典是類似的,它返回一個列表對象

          >>> soup.p['class'][u'bold']

          NavigableString

          獲取標簽中的內容,直接使用 .stirng 即可獲取,它是一個 NavigableString 對象,你可以顯式地將它轉換為 unicode 字符串。

          >>> soup.p.stringu'\u5982\u4f55\u4f7f\u7528BeautifulSoup'>>> type(soup.p.string)<class 'bs4.element.NavigableString'>>>> unicode_str = unicode(soup.p.string)>>> unicode_stru'\u5982\u4f55\u4f7f\u7528BeautifulSoup'

          基本概念介紹完,現在可以正式進入主題了,如何從 HTML 中找到我們關心的數據?BeautifulSoup 提供了兩種方式,一種是遍歷,另一種是搜索,通常兩者結合來完成查找任務。

          遍歷文檔樹

          遍歷文檔樹,顧名思義,就是是從根節點 html 標簽開始遍歷,直到找到目標元素為止,遍歷的一個缺陷是,如果你要找的內容在文檔的末尾,那么它要遍歷整個文檔才能找到它,速度上就慢了。因此還需要配合第二種方法。

          通過遍歷文檔樹的方式獲取標簽節點可以直接通過 .標簽名的方式獲取,例如:

          獲取 body 標簽:

          >>> soup.body<body>\n<h1>BeautifulSoup</h1>\n<p class="bold">\u5982\u4f55\u4f7f\u7528BeautifulSoup</p>\n</body>

          獲取 p 標簽

          >>> soup.body.p<p class="bold">\u5982\u4f55\u4f7f\u7528BeautifulSoup</p>

          獲取 p 標簽的內容

          >>> soup.body.p.string\u5982\u4f55\u4f7f\u7528BeautifulSoup

          前面說了,內容也是一個節點,這里就可以用 .string的方式得到。

          遍歷文檔樹的另一個缺點是只能獲取到與之匹配的第一個子節點,例如,如果有兩個相鄰的 p 標簽時,第二個標簽就沒法通過 .p的方式獲取,這是需要借用 next_sibling 屬性獲取相鄰的節點。

          此外,還有很多不怎么常用的屬性,比如:.contents 獲取所有子節點,.parent 獲取父節點,更多的參考請查看官方文檔。

          搜索文檔樹

          搜索文檔樹是通過指定標簽名來搜索元素,還可以通過指定標簽的屬性值來精確定位某個節點元素,最常用的兩個方法就是 find 和 find_all。這兩個方法在 BeatifulSoup 和 Tag 對象上都可以被調用。

          find_all()

          find_all( name , attrs , recursive , text , **kwargs )

          find_all 的返回值是一個 Tag 組成的列表,方法調用非常靈活,所有的參數都是可選的。

          第一個參數 name 是標簽節點的名字。

          # 找到所有標簽名為title的節點

          >>> soup.find_all("title")

          [<title>hello, world</title>]

          >>> soup.find_all("p")

          [<p class="bold">\xc8\xe7\xba\xce\xca....</p>,
          <p class="big"> \xb5\xda\xb6\xfe\xb8\xf6p...</p>]

          第二個參數是標簽的class屬性值

          # 找到所有class屬性為big的p標簽

          >>> soup.find_all("p", "big")
          [<p class="big"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]

          等效于

          >>> soup.find_all("p", class_="big")
          [<p class="big"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]

          因為 class 是 Python 關鍵字,所以這里指定為 class_。

          kwargs 是標簽的屬性名值對,例如:查找有href屬性值為 “http://foofish.net” 的標簽

          >>> soup.find_all()
          [<a >python</a>]

          當然,它還支持正則表達式

          >>> import re

          >>> soup.find_all(href=re.compile("^http"))
          [<a >python</a>]

          屬性除了可以是具體的值、正則表達式之外,它還可以是一個布爾值(True/Flase),表示有屬性或者沒有該屬性。

          >>> soup.find_all(id="key1")
          [<p class="big" id="key1"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]
          >>> soup.find_all(id=True)
          [<p class="big" id="key1"> \xb5\xda\xb6\xfe\xb8\xf6p\xb1\xea\xc7\xa9</p>]

          遍歷和搜索相結合查找,先定位到 body 標簽,縮小搜索范圍,再從 body 中找 a 標簽。

          >>> body_tag = soup.body

          >>> body_tag.find_all("a")
          [<a >python</a>]

          find()

          find 方法跟 find_all 類似,唯一不同的地方是,它返回的單個 Tag 對象而非列表,如果沒找到匹配的節點則返回 None。如果匹配多個 Tag,只返回第0個。

          >>> body_tag.find("a")

          <a >python</a>

          >>> body_tag.find("p")
          <p class="bold">\xc8\xe7\xba\xce\xca\xb9\xd3\xc3BeautifulSoup</p>

          get_text()

          獲取標簽里面內容,除了可以使用 .string 之外,還可以使用 get_text 方法,不同的地方在于前者返回的一個 NavigableString 對象,后者返回的是 unicode 類型的字符串。

          >>> p1 = body_tag.find('p').get_text()

          實際場景中我們一般使用 get_text 方法獲取標簽中的內容。

          總結

          BeatifulSoup 是一個用于操作 HTML 文檔的 Python 庫,初始化 BeatifulSoup 時,需要指定 HTML 文檔字符串和具體的解析器。它有3類常用的數據類型,分別是 Tag、NavigableString、和 BeautifulSoup。查找 HTML元素有兩種方式,分別是遍歷文檔樹和搜索文檔樹,通常快速獲取數據需要二者結合。

          級鏈接標簽

          1. 語法<a></a>
          2. 必須屬性href=”url”, 它指定鏈接的目標。
          3. 常用屬性 target=”_blank” 在新窗口中打開鏈接
          4. 錨屬性:一般在兩個頁面之間 或者在一個較長的頁面之間 進行通訊所用

          目的頁面的地區用 name屬性定義(name的值可自己定義,一般為英文),鏈接頁面的鏈接應寫為<a href=”url#name”></a>

          1. 在鏈接中,#可用來指代鏈接出發點的頁面本身
          2. 鏈接有四種狀態,在所有瀏覽器中,鏈接的默認外觀是:

          未被訪問的鏈接帶有下劃線而且是藍色的

          已被訪問的鏈接帶有下劃線而且是紫色的

          活動鏈接帶有下劃線而且是紅色的

          關于錨的進一步說明:

          <a> 標簽可定義錨,錨 (anchor) 有兩種用法:

          通過使用 href 屬性,創建指向另外一個文檔的鏈接(或超鏈接)

          通過使用 name 或 id 屬性,創建一個文檔內部的書簽(也就是說,可以創建指向文檔片段的鏈接)


          圖片標簽 <img>

          1、img標簽是一個單標簽,必須和src(source:指出圖像的路徑)屬性連用,

          網頁上圖像的路徑有絕對路徑和相對路徑兩種,但在實際運用中往往只用相對路徑

          絕對路徑:圖片在硬盤上的路徑 (分割符號是/)

          相對路徑:圖片相對于網頁而言的路徑

          如果圖片與網頁在同一個文件夾下,那么可以直接用圖片的名稱表示其路徑

          如果圖片在網頁的下一層文件夾中,比如圖片在網頁文件下面的images文件夾中,則可用images/表示

          我們也可以用./表示網頁所在的文件夾

          如果圖片在網頁的上一層文件夾中,則用../表示

          事實上,不但圖片文件是如此,網頁中應用的文件都分為相對路徑和絕對路徑兩種表達方式。

          2、在網頁上,支持的圖片格式包括.gif .jpg .png .bmp,一般用前三者居多,因為前三者的圖片壓縮比較好。但是,gif格式只有256種顏色,所以,在需要豐富顏色的場合,往往多用jpg和png格式。不過,gif擁有動態功能,而后兩者則不具備。

          3、img標簽可以與其它標簽共處一行,如果有多個圖形出現時,默認為同一行顯示

          4、img標簽有4個常用標簽,分別是

          alt 圖片說明,在圖像無法顯示時表現為圖像的替代文本

          width 寬 屬性值可以是象素,也可以是%

          height 高 屬性值可以是象素,也可以是%

          border 邊框

          5、圖片鏈接仍然是用a標簽來顯示

          例子:<a href=“http://www.rwxy.xnc.edu.cn”><img src="sample.jpg" ></a>

          6、可以用圖像映射實現圖像不同區域的鏈接

          圖象映射

          所謂圖象映射是指一個圖片上的不同位置被指定了不同的超級鏈接;點擊圖片的不同位置會打開不同的超級鏈接目標。這與前面的默認超級鏈把整個圖片作為超級鏈接的元素是很不一樣的。

          圖象映射由<map>定義。<map>有一個基本屬性是name。name給圖象映射命名,這個命名將會被<img>元素用usemap屬性引用。所以,圖象上的圖象映射實際上是對<map>定義的映射的一個引用。

          <map>在定義圖象映射時,可以定義三種形狀的映射: circle(圓形)、rect(矩形rectangle)、poly(多邊形)

          圖象映射實例

          <img src="bear.jpg" usemap="#map" >

          <map name=“map">

          <area shape="rect" coords="46,29,253,164" href="#" >

          <area shape="circle" coords="76,510,59" href="#" >

          <area shape="poly" coords="219,482,253,448,310,462,297,527,220,523" href="#" >

          </map>


          表格標簽

          表格由三個標簽構成,分別是

          <table>...</table> - 定義表格

          <tr> - 定義表行

          <th> - 定義表頭

          <td> - 定義表格單元(表格的具體數據)

          在表格標簽中,table、tr、td標簽都具備不同的屬性

          table:border(邊框尺寸設置);width(表格的寬);height(表格的高);align(橫向對齊:left center right);bgcolor(背景色彩);background(背景圖像);cellspacing(表格單元的間隙設置);cellpadding(表元內部空白設置);

          tr:height(行高);align(橫向對齊:left center right);valign(縱向對齊:top middle bottom);bgcolor(背景色彩);

          td:width(表格的寬);height(表格的高);align(橫向對齊:left center right);valign(縱向對齊:top middle bottom);bgcolor(背景色彩);background(背景圖像);

          注:當talble、tr、td有共同的屬性而且屬性值發生沖突之際,其優先性是td > tr > table

          表格在html中最大的作用不是用來整理數據,而是用來排版,所以它是html中用處最廣的標簽之一。

          表格內部可以繼續放入表格,這被稱之為表格嵌套,利用表格嵌套可以制作出非常復雜的排版。

          表格的單元格可以跨行跨列顯示

          跨多列的單元格 <td colspan=#>

          <table border=1>

          <tr><td colspan=3> morning menu</td>

          <tr><td>food</td> <td>drink</td> <td>sweet</td>

          <tr><td>a</td><td>b</td><td>c</td>

          </table>

          morning menu

          food

          drink

          sweet

          a

          b

          c

          跨多行的單元格 <td rowspan=#>

          <table border=1>

          <tr><td rowspan=3> morning menu</td>

          <td>food</td> <td>a</td></tr>

          <tr><td>drink</td> <td>b</td></tr>

          <tr><td>sweet</td> <td>c</td></tr>

          </table>

          morning menu

          food

          a

          drink

          b

          sweet

          c

          ....................................................................

          我的微信公眾號:UI嚴選 —越努力,越幸運


          ext()方法會把包含的字符轉義處理,html()則不會.所謂轉義就是字符的另一種顯示方法,例如"<" 顯示成 "<",這就是轉義了,其中的<就是<的轉義字符.還有很多可以轉義的字符,可以搜索下看看.


          下邊是項目中用到的2個語句:span中包含了jquery的語句輸出結果.


          1. $('.title').text("<img src=" ">");


          顯示結果為<img src=" ">,這里的<img src=" ">不會被解析成html的img標簽,而是以存字母文字的形式顯示,也就是單純的字符串:<img src=" "> .并且f12查看源碼時看到span包含的<img src=" ">文字內容外層有雙引號哦.看下圖,


          ?


          如果你用右鍵選擇編輯為html,則看到其中的轉義字符<這就說明我們的<被轉移了,


          ?


          如果我們想把<img>顯示成標簽,被瀏覽器解析.那么就需要如下方法.



          2. $('.title').html("<img >");


          顯示結果為解析后的html代碼段,那么這里的<img >就會按照h5的標簽img圖片進行解析顯示了.下圖是f12的頁面代碼結果span中的<img>標簽外層無雙引號,且頁面此時會顯示出來圖片.


          ?



          ?


          主站蜘蛛池模板: 亚洲综合一区国产精品| 人妻少妇久久中文字幕一区二区| 国产午夜精品免费一区二区三区 | 一本久久精品一区二区| 91麻豆精品国产自产在线观看一区| 日韩一区二区超清视频| 无码精品视频一区二区三区| 亚洲片国产一区一级在线观看| 爆乳无码AV一区二区三区| 亚洲美女视频一区| 91香蕉福利一区二区三区| 狠狠色成人一区二区三区| 久久无码人妻精品一区二区三区| 精品日韩一区二区三区视频| 亚洲欧洲专线一区| 无码精品不卡一区二区三区| 亚洲国产系列一区二区三区| 乱色精品无码一区二区国产盗| 亚洲AV美女一区二区三区| 日本在线不卡一区| 亚洲一区综合在线播放| 久久一本一区二区三区| 日韩人妻精品一区二区三区视频| 国产成人欧美一区二区三区| 精品一区二区三区影院在线午夜| 国产精品亚洲一区二区三区 | 国产aⅴ一区二区| 色国产在线视频一区| 日本一区免费电影| 一区二区三区杨幂在线观看| 国产一区二区三区露脸| 女人和拘做受全程看视频日本综合a一区二区视频 | 亚洲AV无码一区二区三区系列| 国产免费一区二区三区在线观看| 麻豆精品久久久一区二区| 中文字幕一区视频| 成人毛片无码一区二区| 一区二区三区观看| 美女一区二区三区| 色欲AV蜜桃一区二区三| 人成精品视频三区二区一区 |