日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DataWhale 组队学习爬虫 Task2

發(fā)布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DataWhale 组队学习爬虫 Task2 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

任務(wù)描述:

2.1 學(xué)習(xí)beautifulsoup

  • 學(xué)習(xí)beautifulsoup,并使用beautifulsoup提取內(nèi)容。

  • 使用beautifulsoup提取丁香園論壇的回復(fù)內(nèi)容。

  • 丁香園直通點:http://www.dxy.cn/bbs/thread/626626#626626 。

  • 參考資料:https://blog.csdn.net/wwq114/article/details/88085875

  • 2.2學(xué)習(xí)xpath

  • 學(xué)習(xí)xpath,使用lxml+xpath提取內(nèi)容。

  • 使用xpath提取丁香園論壇的回復(fù)內(nèi)容。

  • 丁香園直通點:http://www.dxy.cn/bbs/thread/626626#626626 。

  • 參考資料:https://blog.csdn.net/naonao77/article/details/8812999

  • ?

    --------------------------------------------------這是不怎么華麗的分割線-------------------------------------------------

    聲明一下:本文是為了學(xué)習(xí)爬蟲,因此以下的內(nèi)容可能是跟著以上鏈接中的教程操作一遍,有與原文相同的部分,該部分的版權(quán)歸原作者所有。若有錯誤,請朋友指正。

    ?

    1. 學(xué)習(xí)beautifulsoup

    一、Beautifulsoup是一個包,將前面獲取到的html編碼變成一個樹狀的結(jié)構(gòu)。 HTML頁面的代碼其實就是一個樹狀的結(jié)構(gòu):

    最開始是<!DOCTYPE html>

    并列往下<html lang="zh-cn">

    在往下:<head></head>。 head之中就會開始有樹形的結(jié)構(gòu)標簽,比如有<style><\style>,<meta><\meta>,然后style中又有其他。

    head并列往下就會有<>body<\body>, body中有多個div,div中又有其他比如標簽,比如td,tr,a。

    二、獲取到html的信息后,導(dǎo)入beautifulsoup包,使用find函數(shù)再去獲取需要的內(nèi)容。

    find函數(shù)用法:
    find(name, attrs, recursive, text, **wargs) # recursive 遞歸的,循環(huán)的
    這些參數(shù)相當于過濾器一樣可以進行篩選處理。不同的參數(shù)過濾可以應(yīng)用到以下情況:
    查找標簽,基于name參數(shù)
    查找標簽的屬性,基于attrs參數(shù)
    查找文本,基于text參數(shù)
    基于正則表達式的查找
    基于函數(shù)的查找

    代碼實現(xiàn):

    使用urllib.request獲取html

    from urllib import requesturl = 'http://www.dxy.cn/bbs/thread/626626' headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Firefox/60.0'} req = request.Request(url=url, headers=headers) res = request.urlopen(req).read() print(res.decode('utf-8')) #打印時要轉(zhuǎn)碼with open('dxy.html', 'wb') as f:f.write(res) #寫入文件時,不要轉(zhuǎn)碼

    返回的打印內(nèi)容及保存的dxy.html文件,文件大小69k。

    注意:這里遇到一個問題,就是python中用print打印出來時,需要decode('utf-8'),保存成html文件時,不要轉(zhuǎn)碼,直接用read()的結(jié)果寫入。

    使用beautifulsoup的find函數(shù)獲取標簽內(nèi)容

    從流浪器網(wǎng)頁f12后,可以看到用戶名在div class='auth'中(圖一),評論內(nèi)容在td class='postbody'中(圖二),而每一段評論的所有內(nèi)容都包含在一個tbody中,其實往上一層,是包含在一個div中(圖三)。

    因此教程里面用一個findall,找到所有的tbody,其實用findall找div也可以,但比較浪費資源

    找到所有的tbody后,就開始找具體的名字和評論內(nèi)容,找不到則要跳過,因此用一個try功能實現(xiàn)。

    圖一:?

    圖二:?

    圖三:?

    代碼實現(xiàn):

    from bs4 import BeautifulSoup as bs html = bs(res,'lxml')datas = [] #用來獲取所有遍歷到的結(jié)果 for data in html.find_all("tbody"):try:username = data.find("div", class_="auth").get_text(strip=True)print(username)content = data.find('td', class_='postbody').get_text(strip=True)print(content)datas.append((username,content)) #內(nèi)層的括號,將每一個結(jié)果的子結(jié)果組合起來except:pass # 找不到就pass,因為findall找到的tbody中,可能沒有對應(yīng)的auth和postbody,上面tbody換成div也是可以的!print(datas)

    由以上代碼可以看到:

    findall返回的結(jié)果是tboday的內(nèi)容,findall返回的多個符合條件的結(jié)果,可以用一個for循環(huán)每一個結(jié)果,每一個結(jié)果又可以用find函數(shù)把對應(yīng)的標簽內(nèi)容找到。

    返回的結(jié)果:

    ?


    ?

    2. 學(xué)習(xí)xpath

    Xpath - 用于確定XML文檔中某部分位置的語言。

    XPath 中,有七種類型的節(jié)點:元素、屬性、文本、命名空間、處理指令、注釋以及文檔(根)節(jié)點。XML 文檔是被作為節(jié)點樹來對待的。

    • XPath 用“/”來作為上下層級間的分隔,第一個“/”表示文檔的根節(jié)點<html></html>
    • 定位某一個HTML標簽,可以用
      絕對路徑:如 page_content.xpath(u"/html/body/p"),找到body下的所有p表情
      ??? 或
      相對路徑:如 page_content.xpath(u"//p"),找到整個html中的所有p標簽
    • 添加過濾條件:
      page_content.xpath(u"//p[@style='font-size: 200%']")? # 標簽屬性中有style='font-size: 200%
      page_content.xpath(u"//p[text() = 'hello']")?? #標簽的文本內(nèi)容包含'hello'
      page_content.xpath(u"//div/ul/li[position() = 2]") #所有div中ul的第二個li標簽,可簡化為...li[2]
      數(shù)字定位和過濾條件的順序:

      ??? ul/li[5][@name='hello'] - ul第五個li,且name='hello',否則返回空
      ??? ul/li[@name='hello'][5] - ul下,第五個name為hello的標簽,否則返回空
    • 通配符 * 可以代替所有的節(jié)點名,/html/body/*/span 代表body下的所有span標簽

    • descendant:: 代表任意多層的中間節(jié)點,可以省略成一個 /
      /descendant::div[@id='leftmenu'] 或 //div[@id='leftmenu']? 所有id為leftmenu的div

    • page.xpath(u"/descendant::*[text()]")
      表示任意多層的中間節(jié)點(相同的節(jié)點)下任意標簽之間的內(nèi)容,也即實現(xiàn)蜘蛛抓取頁面內(nèi)容功能。

    • 不同節(jié)點之間的內(nèi)容獲取 (假如需要獲取"取不到的內(nèi)容"這幾個字,該怎么做的?)
      xpath(u"//div[tail='<br />']")??? # 失敗.....:(
      xpath(u"/body/div[tail]")? ? # 失敗.....:( <div class="news">1. <b>無流量站點清理公告</b>&nbsp;&nbsp;2013-02-22<br/>取不到的內(nèi)容 </div> <div class="news"> 2. <strong>無流量站點清理公告</strong>&nbsp;&nbsp;2013-02-22<br />取不到的內(nèi)容 </div> <div class="news"> 3. <span>無流量站點清理公告</span>&nbsp;&nbsp;2013-02-22<br />取不到的內(nèi)容 </div>
    • following-sibling:: 同一層的下一個節(jié)點

    • 使用模塊 lxml.html.clean 的一個Cleaner 類來清理 HTML 頁
      支持刪除嵌入或腳本內(nèi)容、 特殊標記、 CSS 樣式注釋或者更多
      ??? cleaner = Cleaner(style=True, scripts=True,page_structure=False, safe_attrs_only=False)
      ??? # 注意,page_structure,safe_attrs_only為False時保證頁面的完整性,否則,這個Cleaner會把你的html結(jié)構(gòu)與標簽里的屬性都給清理了。
      ??? print(cleaner.clean_html(html))

    • 忽略大小寫可以:

        page = etree.HTML(html)
        keyword_tag = page.xpath("//meta[translate(@name,'ABCDEFGHJIKLMNOPQRSTUVWXYZ', 'abcdefghjiklmnopqrstuvwxyz')='keywords']")

      ?

    語法格式:

    from lxml import etree:

    html_document = ''' HTML 文檔 '''

    tree = etree.HTML(html_document.lower().decode('utf-8'))?? # 需要用utf-8解碼

    elements = page_content.xpath(u"//標簽")?? # 根目錄下的所有a標簽元素

    for element in elements :

    ??? print(element.attrib) ?? # 打印標簽的屬性

    ??? print(element.text) ?? # 打印標簽的內(nèi)容

      使用lxml前注意事項:先確保html經(jīng)過了utf-8解碼,即code = html.decode('utf-8', 'ignore'),否則會出現(xiàn)解析出錯情況。因為中文被編碼成utf-8之后變成 '/u2541' 之類的形式,lxml一遇到 “/”就會認為其標簽結(jié)束。

    參考別人的例子:

    html_document=''' <html><head><meta name="content-type" content="text/html; charset=utf-8" /><title>友情鏈接查詢 - 站長工具</title><!-- uRj0Ak8VLEPhjWhg3m9z4EjXJwc --><meta name="Keywords" content="友情鏈接查詢" /><meta name="Description" content="友情鏈接查詢" /></head><body><h1 class="heading">Top News</h1><p style="font-size: 200%">World News only on this page</p>Ah, and here's some more text, by the way.<p>... and this is a parsed fragment ...</p><a href="http://www.cydf.org.cn/" rel="nofollow" target="_blank">青少年發(fā)展基金會</a><a href="http://www.4399.com/flash/32979.htm" target="_blank">洛克王國</a><a href="http://www.4399.com/flash/35538.htm" target="_blank">奧拉星</a><a href="http://game.3533.com/game/" target="_blank">手機游戲</a><a href="http://game.3533.com/tupian/" target="_blank">手機壁紙</a><a href="http://www.4399.com/" target="_blank">4399小游戲</a><a href="http://www.91wan.com/" target="_blank">91wan游戲</a></body> </html> '''from lxml import etree tree= etree.HTML(html_document.lower()) # page_content = etree.HTML(html_document.lower().decode('utf-8)) # 這里使用decode('utf-8')出錯了,string類型只有encode()屬性? # 或許是因為文本已經(jīng)是解碼過的 # 嘗試改為page_content = etree.HTML(html_document.lower().encode('utf-8)), # 反而沒報錯但出現(xiàn)亂碼 elements = tree.xpath(u"//a") for element in elements:print(element.attrib) #打印出來是字典類型print(element.text) #打印出來是文本類型print('--'*20)

    返回:

    注意:

    page_content = etree.HTML(html_document.lower().decode('utf-8)),這里面的decode需要根據(jù)前面的對象使用,上面舉的例子用文本,文本沒有decode('utf-8)的屬性.....

    element.attrib 結(jié)果是字典類

    element.text 結(jié)果是文本

    參考:https://www.cnblogs.com/descusr/archive/2012/06/20/2557075.html

    ?

    Xpath 案例

    參考https://blog.csdn.net/naonao77/article/details/88129994

    待補充。。。。

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    --- End ---

    總結(jié)

    以上是生活随笔為你收集整理的DataWhale 组队学习爬虫 Task2的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。