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 婷婷综合缴情亚洲五月伊,嫩草影院久久精品,狠狠色伊人亚洲综合成人

          整合營銷服務商

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

          免費咨詢熱線:

          深入解析網頁結構解析模塊beautifulsoup

          深入解析網頁結構解析模塊beautifulsoup

          家好,我是編程末白,今天給大家分享一個網頁結構解析模塊beautifulsoup。

          前言

          beautifulsoup(以下簡稱bs),是一款網頁結構解析模塊,它支持傳統的Xpath,css selector 語法,可以說很強大了,下面我們就來著重介紹下它的用法。

          安裝

          bs 可以使用pip 或者easy_install安裝,方便快捷。

          pip install Beautifulsoup4 


          基本用法

          一般就是先由requests 獲取到網頁源碼后然后對頁面進行解析,如圖:

          這樣就基本上拿到了頁面的源碼了。

          1.根據標簽直接獲取元素,如下圖:


          2.根據find,find_all方法查找

          前者返回一個結果,后者返回所有結果

          find( name , attrs , recursive , text , **kwargs )
          
          
          name :要查找的標簽名(字符串、正則、方法、True)
          
          
          attrs: 標簽的屬性
          
          
          recursive: 遞歸
          
          
          text: 查找文本
          
          
          **kwargs :其它 鍵值參數

          因為class是關鍵字,所以要寫成class_="value", 等同于attrs={"class":"value"}

          這里的參數適用于find find_all兩種方法。

          只不過find_all 還有其他參數,比如限制查找返回數量 的limit方法,標簽內容string方法。


          3.根據select方法查找

          soup.select('div')

          所有名為<div>的元素

          soup.select('#aa')

          所有 id 屬性名為aa的元素

          soup.select('.oo')

          所有class 屬性名為oo的元素

          soup.select('div p')

          所有在<div>元素之內的<p>元素

          soup.select('div >p')

          所有直接在<div>元素之內的<p>元素,中間沒有其他元素

          soup.select('input[name]')

          所有名為<input>,并有一個 name 屬性,其值無所謂的元素

          soup.select('input[type="button"]')

          所有名為<input>,并有一個 type 屬性,其值為 button 的元素

          soup.select('a')[0].get_text() # 獲取首個a元素的文本

          soup.select('a')[0].attrs['href'] # 獲取首個a元素的鏈接地址


          4.關系節點名

          find_parents()返回所有祖先節點的列表,find_parent()返回直接父節點
          
          
          print(soup.title.find_parent())
          
          
          print(soup.title.find_parent().find_all('link')[1])
          
          
          print(soup.title.find_parents())
          
          
          find_next_siblings()返回后面所有兄弟節點的列表,find_next_sibling()返回后面第一個兄弟節點
          
          
          print(soup.title.find_next_sibling())
          
          
          print(soup.title.find_next_siblings())
          
          
          find_previous_siblings()返回前面所有兄弟節點的列表,find_previous_sibling()返回前面第一個兄弟節點
          
          
          print(soup.title.find_previous_sibling())
          
          
          print(soup.title.find_previous_siblings())
          
          
          find_all_next()返回節點后所有符合條件的節點的列表, find_next()返回節點后第一個符合條件的節點
          
          
          print(soup.title.find_next('link'))
          
          
          print(soup.title.find_all_next('link'))
          
          
          find_all_previous()返回節點前所有符合條件的節點, find_previous()返回節點前第一個符合條件的節點
          
          
          print(soup.title.find_previous('link'))
          
          
          print(soup.title.find_all_previous('link'))


          5.對象種類

          tag(標簽)  navigablestring(標簽內字符串)  beautifulsoup(對象)  comment(備注)
          
          
          rep=requests.get('https://book.qidian.com/info/1014243481#Catalog',timeout=3)
          soup=BeautifulSoup(rep.text,'html.parser')
          
          
          print(soup.name)  #beautifulsoup 對象
          
          
          tr=soup.div
          
          
          print(type(tr),tr) #tag對象 標簽
          
          
          print(tr.get_attribute_list('class')) #獲取屬性對應列表
          
          
          print(tr.a.string) #navigablestring 對象,獲取標簽內文字,可使用str()方法將她轉換為unicode字符串
          print(soup.a.string.replace_with('fdf')) #替換navigablestring

          comment 即為提取的注釋內容,一般為!--xxxxxxx--! 包裹的內容就是了


          三、使用案例

          爬取起點小說主頁第一頁所有小說名字和鏈接,如圖:

          import requests
          from bs4 import BeautifulSoup
          rep=requests.get('https://www.qidian.com/all',timeout=3)
          soup=BeautifulSoup(rep.text,'html.parser')
          #按照步驟一步一步來爬取
          ul=soup.find_all('ul','all-img-list cf')
          for y in ul: 
              for z in y.find_all('div','book-mid-info'):
                  for x in z.find_all('h4'):
                      for v in x.find_all('a'):
                          print(v.get_text(),'https:'+v.attrs['href']) #獲取a標簽的內容和href屬性值

          最后就可以得出正確結果,如圖:

          關于bs大致就這么多,大家學會了嗎??


          總結

          今天就講這么多,關于BS的強大之處,遠不止于此,本文只是介紹了它的安裝和基本用法,并通過一個案例來幫助大家加深理解,希望大家好好利用,在爬蟲路上可以事倍功半!

          ------------------- End -------------------

          最后多說一句,小編是一名python開發工程師,這里有我自己整理了一套最新的python系統學習教程,包括從基礎的python腳本到web開發、爬蟲、數據分析、數據可視化、機器學習等。想要這些資料的可以關注小編,并在后臺私信小編:“01”即可領取。

          上一節中,認識了Python中的lxml庫,可以通過XPath來尋找頁面中的位置,這也是僅僅對于結構完整的頁面,但是對于有針對性的獲取內容的時候并不很友好,比如說鏈接中以XXX開頭或者結尾,而且中間符合某些特定規則,所以這時候需要認識一個新朋友,那就是另外一個很強大的解析庫——Beautiful Soup。

          與 lxml 一樣,Beautiful Soup 也是一個HTML/XML的解析器,通過解析文檔為用戶提供需要抓取的數據的功能。

          安裝BeautifulSoup

          Beautiful Soup也有很多版本,不過Beautiful Soup3已經停止更新了,目前最新的都是Beautiful Soup4,而且也已經移植到bs4庫中,我們安裝bs4庫后就可以直接使用。安裝庫使用pip安裝,安裝命令:

          pip install beautifulsoup4

          安裝解析器

          Beautiful Soup中支持的解析器有很多種,不僅僅支持Python標準庫中的HTML解析器,還可以使用一些第三方的解析器,比如說lxml等,如表所示,是幾種常見的解析器的優缺點。

          解析器

          使用方式

          優點

          缺點

          Python標準庫

          BeautifulSoup(html, "html.parser")

          Python的內置標準庫、文檔容錯性較強

          執行速度適中

          lxml解析器

          BeautifulSoup(html, "lxml")

          速度快、文檔容錯性較強

          依賴C語言庫

          html5lib

          BeautifulSoup(html, "html5lib")

          以瀏覽器的方式解析文檔、容錯性最好

          執行速度慢

          一般情況下可以使用Python標準庫或者lxml作為常用的解析器,對于爬蟲來說,比起速度來說,準確性的要求并不是很高。如果在解析文檔上花費的時間太多,必然會導致爬蟲的效率低。

          Python標準庫解析器并不需要安裝,因為本身自帶的,lxml解析器在上一節使用它作為解析器時候已經安裝過了,也不需要額外安裝,直接使用即可。html5lib的安裝跟BeautifulSoup一樣,使用pip安裝:

          pip install html5lib

          生成解析對象

          from bs4 import BeautifulSoup
          from lxml import etree
          text='''
          <html>
          <head>
          <title>實例HTML</title>
          </head>
          <body>
          <div>
          <h1>這是標題</h1>
          </div>
          <div>
          <ul>
          <li class="c1"><a href="link1.html" title="鏈接1">第一個鏈接</a></li>
          <li class="c2"><a href="link2.html" title="鏈接2">第二個鏈接</a></li>
          <li class="c3"><a href="link3.html" title="鏈接3">第三個鏈接</a></li>
          </ul>
          </div>
          </body>
          </html>
          '''
          # 生成一個BeautifulSoup對象
          soup=BeautifulSoup(text, 'html.parser')
          # 對象類型
          print(type(soup))
          #代碼結果:
          <class 'bs4.BeautifulSoup'>

          現在就獲得了一個BeautifulSoup的對象,Beautiful Soup其實是將HTML文檔轉換成一個復雜的樹形結構,每個節點都是Python中的對象,所有對象可以歸納為 4 種:Tag、NavigableString、BeautifulSoup、Comment,后兩種根本上講也是前面兩種的特殊情況。下面我們簡要講解這幾個對象。

          Tag

          Tag是最容易理解的,跟字面意思一樣,就是HTML中的標簽。比如:一個a標簽就是一個對象:

          <a href="link1.html" title="鏈接1">第一個鏈接</a>

          在tag對象中比較重要的兩個屬性name和attrs。通過這兩個屬性可以獲取到標簽中的信息:

          print(soup.a.name)
          print(soup.a.attrs)
          #代碼結果:
          a
          {'href': 'link1.html', 'title': '鏈接1'}

          name其實就是獲取標簽的名稱,這個是使用的不多,畢竟在日常使用的時候都會知道需要找哪些標簽中的內容。attrs獲取是標簽中的屬性,結果是一個字典類型的集合。

          NavigableString

          在上面兩個屬性中,并沒法獲取標簽中的內容,那么NavigableString就是用來獲取標簽中文本內容的,用法也比較簡單,直接使用string即可。

          print(soup.a.string)
          print(type(soup.a.string))
          #代碼結果:
          第一個鏈接
          <class 'bs4.element.NavigableString'>

          BeautifulSoup

          這個對象在前面提到過,表示一個頁面(文檔)的內容,可以作為一個特殊的Tag。

          print(type(soup))
          #代碼結果:
          <class 'bs4.BeautifulSoup'>

          Comment

          Comment對象也是一個特殊的NavigableString,讀取的內容是注釋里面的內容。把上面示例中的第一個a標簽的內容更改成如下:

          <a href="link1.html" title="鏈接1"><!--Hello--></a>
          print(soup.a.string)
          print(type(soup.a.string))
          #代碼結果:
          Hello
          <class 'bs4.element.Comment'>

          注意:如果在標簽內的文本既有正常文字也有注釋,這時候string屬性就無法獲取到內容:

          <a href="link1.html" title="鏈接1">第一個鏈接<!--Hello--></a>
          print(soup.a.string)
          #代碼結果:
          None

          獲取文本內容可以使用text方法,雖然text和string結果都是字符串,但是兩個對象其實并不相同。

          <a href="link1.html" title="鏈接1">第一個鏈接<!--Hello--></a>
          print(soup.a.text)
          print(type(soup.a.text))
          #代碼結果:
          第一個鏈接
          <class 'str'>

          搜索文檔樹

          把HTML內容解析成為一個BeautifulSoup對象后,對這個對象的操作才是BeautifulSoup這個模塊所能體驗的強大之處。本身BeautifulSoup本身有著豐富的節點遍歷功能,包括父節點、子節點、子孫節點的獲取和逐個元素的遍歷。

          不過在實際應用上,我們使用遍歷的還是少數,使用搜索的還是多數,現在很多網頁中的元素很豐富,我們很少會把一個頁面中的所有內容都獲取下來,基本是需要的重點內容,這對于遍歷來說,搜索更加顯得便捷實用。

          find_all()

          說到搜索,最常使用的肯定是BeautifulSoup的find_all()方法,它會搜索當前 tag 的所有 tag 子孫節點,并判斷每個節點是否符合過濾器的條件。

          find_all()方法的完整參數為find_all(name, attrs, recursive, text,limit, **kwargs):

          name:標簽名稱的過濾,支持正則

          attrs:標簽的屬性條件的過濾,支持正則;

          recursive:bool選項,如果為True,find_all()將遍歷所有節點,否則只有子節點,默認為True;

          text:標簽中的文本過濾,;

          limit:搜索限制過濾,如果不為空,表示找到指定數量的元素后將停止搜索,默認為空,將搜索全部;

          kwargs:表示可以添加多個屬性值參數過濾。

          1.name參數

          搜索所有a標簽

          links=soup.find_all('a')
          print(links)

          代碼結果:

          [<a href="link1.html" title="鏈接1">第一個鏈接</a>, <a href="link2.html" title="鏈接2">第二個鏈接</a>, <a href="link3.html" title="鏈接3">第三個鏈接</a>]

          搜索所有名字帶“a”標簽

          links=soup.find_all(re.compile(".*a.*"))
          print(links)

          代碼結果(head和a標簽都符合)

          [<head>
          <title>實例HTML</title>
          </head>, <a href="link1.html" title="鏈接1">第一個鏈接</a>, <a href="link2.html" title="鏈接2">第二個鏈接</a>, <a href="link3.html" title="鏈接3">第三個鏈接</a>]

          2. arrts參數

          搜索所有a標簽中title值為“鏈接1”

          links=soup.find_all('a', attrs={"title": "鏈接1"})
          print(links)

          代碼結果:

          [<a href="link1.html" title="鏈接1">第一個鏈接</a>]

          3. kwargs參數:

          搜索所有a標簽中herf中帶“1”的標簽

          links=soup.find_all('a', href=re.compile(".*1.*"))
          print(links)

          代碼結果:

          [<a href="link1.html" title="鏈接1">第一個鏈接</a>]

          4. text參數:

          #搜索所有a標簽中,文本帶“二”的標簽

          links=soup.find_all('a', text=re.compile(".*二.*"))
          print(links)

          代碼結果:

          [<a href="link2.html" title="鏈接2">第二個鏈接</a>]

          如果不加a標簽,搜索的內容則僅僅是文本。

          #搜索所有a標簽中,文本帶“二”的標簽

          links=soup.find_all('text=re.compile(".*二.*"))
          print(links)

          代碼結果:

          ['第二個鏈接']

          5. limit參數

          #搜索所有a標簽中,超鏈接以link開頭,最多2個

          links=soup.find_all('a', href=re.compile("link.*"), limit=2)
          print(links)

          代碼結果:

          [<a href="link1.html" title="鏈接1">第一個鏈接</a>, <a href="link2.html" title="鏈接2">第二個鏈接</a>]

          find()

          find()方法相當于給find_all()方法默認添加limit=1,僅僅發揮符合條件的第一個Tag。方便有時候我們僅僅需要一個值的時候,直接可以調用。參數跟find_all()一樣,用法也是相同。

          CSS選擇器

          Beautiful Soup中用select()方法來CSS樣式的進行篩選,當然也可以篩選標簽。在標簽的屬性中,class的屬性就是當前標簽的CSS樣式,返回的結果同樣也是list。

          1.通過標簽名查找

          查找所有a標簽

          links=soup.select('a')
          print(links)

          代碼結果:

          [<a href="link1.html" title="鏈接1">第一個鏈接</a>, <a href="link2.html" title="鏈接2">第二個鏈接</a>]

          2.通過CSS樣式類名查找

          查找樣式類名為c1的標簽

          links=soup.select('.c1')
          print(links)

          代碼結果:

          [<li class="c1"><a href="link1.html" title="鏈接1">第一個鏈接</a></li>]

          3.通過標簽屬性查找

          查找屬性中href="link1.html"的a標簽

          links=soup.select('a[href="link1.html"]')
          print(links)

          代碼結果:

          [<a href="link1.html" title="鏈接1">第一個鏈接</a>]

          在標簽+屬性組合中,屬性不支持正則表達式。

          4.獲取查找到的內容

          除了以上集中還可以使用標簽的id等元素來進行查找,但是不管使用哪種方式,最終的是回去標簽的內容或者屬性中的值,那么找到相應的標簽后,怎么取值呢?如果是去標簽屬性值,跟使用字典取值方式一樣。如果是獲取標簽的文本,直接使用get_text()方法,可以獲取到標簽的文本內容。

          查找屬性中href="link1.html"的a標簽

          links=soup.select('a[href="link1.html"]')
          #打印標簽中的超鏈接值
          print(links[0][‘href])
          #打印標簽文本內容
          print(links[0].get_text())

          代碼結果:

          第一個鏈接
          link1.html

          不管是使用lxml還是Beautiful Soup,多數結果都是獲取文本內容或者是標簽的屬性值。文本內容多數是需要獲取的內容,整理下來放到list中,最后可能保存本地文件或者數據庫,而標簽的中屬性值多數可以找到子鏈接(詳情鏈接),知道了怎么定位和獲取頁面的元素,下面我們就可以動手爬取頁面的內容了。

          eautifulsoup介紹:

          1. 是一個高效的網頁解析庫,可以從HTML或XML文件中提取數據
          2. 支持不同的解析器,比如,對HTML解析,對XML解析,對HTML5解析
          3. 就是一個非常強大的工具,爬蟲利器
          4. 一個靈活又方便的網頁解析庫,處理高效,支持多種解析器
          5. 利用它就不用編寫正則表達式也能方便的實現網頁信息的抓取


          第一步:安裝BeautifulSoup4,lxml

           pip install BeautifulSoup4
              BeautifulSoup 是一個可以從HTML或XML文件中提取數據的Python庫
          pip install lxml
              lxml 是一種使用 Python 編寫的解析庫,可以迅速、靈活地處理 XML 和 HTML


          第二步:導包,from bs4 import BeautifulSoup


          第三步:實例化對象

          html="""
          <html>
              <head>
                  <title>The Dormouse's story</title>
              </head>
              <body>
                  <p class="story">
                      Once upon a time there were three little sisters; and their names were
                      <a href="http://example.com/elsie" class="sister" id="link1">
                          <span>Elsie</span>
                      </a>
                      <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> 
                      and
                      <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>
                      and they lived at the bottom of a well.
                  </p>
                  <p class="story">...</p>
          """
          soup=BeautifulSoup(html, 'lxml')  # h:要解析的內容  lxml:解析器
          知識補充:print(soup.prettify())  # 代碼補全


          第四步:打印

          一、通過標簽選取,會返回包含標簽本身及其里面的所有內容

          # print(soup.head) # 包含head標簽在內的所有內容
          # print(soup.p) # 返回匹配的第一個結果

          1.print(soup.head)打印結果:

          <head>

          <title>The Dormouse's story</title>

          </head>

          2.print(soup.p)打印結果:

          <p class="title" name="dromouse"><b><span>The Dormouse's story</span></b></p>


          二、打印標簽中間的文本內容,不包含<>

          # .string是屬性,作用是獲取字符串文本
          print(soup.html.head.title.string)
          print(soup.title.string)

          打印結果都為:The Dormouse's story


          三、打印標簽名

           .name --獲取標簽本身名稱  
           print(soup.title.name)

          打印結果為:title


          四、打印屬性的值

          .attrs[]  --通過屬性拿屬性的值 
          print(soup.p.attrs['name'])# 獲取p標簽name屬性的屬性值
          print(soup.a.attrs['id']) # 獲取p標簽id屬性的屬性值
          
          print(soup.a['id']) #第二種寫法
          print(soup.p['class']) # 以列表得形式保存
          print(soup.a['href'])  # 也是只返回第一個值

          1.print(soup.p.attrs['name'])打印結果:

          dromouse

          2.print(soup.p.attrs['id'])和print(soup.a['id'])打印結果:

          link1

          3.print(soup.p['class'])打印結果:

          ['title', 'asdas']

          4.print(soup.a['href'])打印結果:

          http://example.com/elsie


          五、打印父標簽下的所有子標簽

          .contents 獲取標簽子節點,以列表形式返回
          .children 獲取子節點,返回的是一個list類型的迭代器
          
          print(soup.body.contents)  # a是p的子節點,獲取P標簽所有子節點內容 返回一個list
          print(soup.body.children) #返回的是一個list類型的迭代器

          1.print(soup.body.contents)的打印結果:

          ['\n', <p class="title asdas" name="dromouse"><b><span>The Dormouse's story</span></b></p>, '\n', <p class="story">Once upon a time there were three little sisters; and their names were

          <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,

          <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and

          <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;

          and they lived at the bottom of a well.</p>, '\n', <p class="story">...</p>, '\n']

          2.print(soup.body.children)的打印結果:

          <list_iterator object at 0x000002035ECC7088>


          .children 獲取子節點講解

          1.和for循環一起使用

          for i in soup.p.children:
          print(i)

          打印結果:


          主站蜘蛛池模板: 亚洲av色香蕉一区二区三区 | 成人精品视频一区二区三区| 天堂Aⅴ无码一区二区三区| 亚洲AV无一区二区三区久久| 日本一区二区三区久久| 无码精品人妻一区二区三区人妻斩| 亚洲av永久无码一区二区三区| 国产一区二区三区高清在线观看| 春暖花开亚洲性无区一区二区 | 99精品一区二区三区无码吞精 | 国产在线无码视频一区二区三区| 午夜一区二区在线观看| 日韩好片一区二区在线看| 久久国产高清一区二区三区 | 相泽亚洲一区中文字幕| 国偷自产视频一区二区久| 亚洲一区在线观看视频| 亚洲av一综合av一区| 波多野结衣的AV一区二区三区 | 精品一区二区三区视频在线观看 | 亚洲av午夜福利精品一区人妖| 精品福利一区二区三区精品国产第一国产综合精品 | 少妇精品无码一区二区三区 | 无码一区二区三区视频| 久久精品国产第一区二区| 亚洲av成人一区二区三区在线观看 | 日韩精品中文字幕视频一区| 人妻在线无码一区二区三区| 91精品乱码一区二区三区| 日本免费一区二区三区四区五六区| 中文字幕一区二区三区永久| 亚洲福利视频一区二区| 亚洲国产成人精品久久久国产成人一区二区三区综 | 无码日本电影一区二区网站| 国产精品亚洲一区二区麻豆| 精品人妻中文av一区二区三区| 亚洲AV综合色一区二区三区| 无码乱人伦一区二区亚洲| 无码精品人妻一区二区三区免费看| 日本一区精品久久久久影院| 无码人妻视频一区二区三区|