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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

Python爬虫与信息提取(五)爬虫实例:爬取新浪微博热搜排名

發(fā)布時(shí)間:2024/1/8 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python爬虫与信息提取(五)爬虫实例:爬取新浪微博热搜排名 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

經(jīng)過(guò)一段時(shí)間的Python網(wǎng)絡(luò)爬蟲學(xué)習(xí),今天自己摸索制作了一個(gè)能夠爬取新浪微博實(shí)時(shí)熱搜排名的小爬蟲

1.效果:

2.制作過(guò)程中遇到的問(wèn)題:

(1)一開始研究微博熱搜頁(yè)面的源代碼時(shí)忽略了<tbody>中還包括一個(gè)置頂熱搜,它的標(biāo)簽包含結(jié)構(gòu)和其他的50個(gè)不同,因此需要單獨(dú)考慮

(2)難點(diǎn)是標(biāo)簽中信息的獲取,需要搞清楚 find_all( ) 函數(shù)返回的是列表,只能用于for遍歷體系中,針對(duì)HTML中的<tbody>下面的<tr>節(jié)點(diǎn),<tr>下面的<tb>子節(jié)點(diǎn),都需要一步一步地find

(3)在一開始不知道如何使用class="td-01"屬性直接find到內(nèi)容,因?yàn)閜ython的關(guān)鍵字class會(huì)和class=發(fā)生重名的情況,經(jīng)過(guò)查閱之后發(fā)現(xiàn),可以使用 class_ 代替 class

https://blog.csdn.net/IMW_MG/article/details/78109199

(4)在獲取的時(shí)候曾經(jīng)遇到了問(wèn)題:使用<>.string獲取不到標(biāo)簽中的字符串內(nèi)容,這種情況會(huì)在熱搜排名中帶有表情emoji時(shí)發(fā)生,經(jīng)過(guò)調(diào)試得到了將string替換為text的解決方法,可以正常地得到字符串的內(nèi)容

(5)正確地獲取到一個(gè)存儲(chǔ)信息的二維列表之后,還需要按照格式從而正確地打印出來(lái),這又是一個(gè)難點(diǎn)。一直遇到了一個(gè)問(wèn)題:在中英混合的字符串中,內(nèi)置的len( )函數(shù)無(wú)法正確地計(jì)算字符串的字符長(zhǎng)度(不是長(zhǎng)度!),從而導(dǎo)致了輸出排版不整齊的問(wèn)題。經(jīng)過(guò)查閱之后,有下面的內(nèi)容解決了這樣的問(wèn)題:

https://www.jb51.net/article/86577.htm

?于是內(nèi)建了函數(shù)length( )來(lái)正確獲取字符串的字符寬度,從而正確計(jì)算所需空格的數(shù)量

#獲取一個(gè)中英文混合的字符串文本的字符寬度部分 widths = [(126, 1), (159, 0), (687, 1), (710, 0), (711, 1),(727, 0), (733, 1), (879, 0), (1154, 1), (1161, 0),(4347, 1), (4447, 2), (7467, 1), (7521, 0), (8369, 1),(8426, 0), (9000, 1), (9002, 2), (11021, 1), (12350, 2),(12351, 1), (12438, 2), (12442, 0), (19893, 2), (19967, 1),(55203, 2), (63743, 1), (64106, 2), (65039, 1), (65059, 0),(65131, 2), (65279, 1), (65376, 2), (65500, 1), (65510, 2),(120831, 1), (262141, 2), (1114109, 1), ] def get_width(a):global widthsif a == 0xe or a == 0xf:return 0for num, wid in widths:if a <= num:return widreturn 1 def length(str):sum = 0for ch in str:sum += get_width(ord(ch))return sum

3.全部代碼

import requests import re import bs4#獲取一個(gè)中英文混合的字符串文本的字符寬度部分 widths = [(126, 1), (159, 0), (687, 1), (710, 0), (711, 1),(727, 0), (733, 1), (879, 0), (1154, 1), (1161, 0),(4347, 1), (4447, 2), (7467, 1), (7521, 0), (8369, 1),(8426, 0), (9000, 1), (9002, 2), (11021, 1), (12350, 2),(12351, 1), (12438, 2), (12442, 0), (19893, 2), (19967, 1),(55203, 2), (63743, 1), (64106, 2), (65039, 1), (65059, 0),(65131, 2), (65279, 1), (65376, 2), (65500, 1), (65510, 2),(120831, 1), (262141, 2), (1114109, 1), ] def get_width(a):global widthsif a == 0xe or a == 0xf:return 0for num, wid in widths:if a <= num:return widreturn 1 def length(str):sum = 0for ch in str:sum += get_width(ord(ch))return sum#獲取HTML文本 def getHTMLText(url):try:#模擬瀏覽器kv = {'user-agent':'Mozilla/5.0'}r = requests.get(url, headers=kv, timeout=30) r.raise_for_status()r.encoding = r.apparent_encodingreturn r.textexcept:print("InternetError!")return " "#解析并且返回HTML文本 def HTMLTextconvert(html):try:soup = bs4.BeautifulSoup(html, "html.parser")return soupexcept:print("HTMLConvertError!")return " "#檢索HTML中的信息,獲取搜索排名信息 #存在置頂?shù)那闆r,需要特殊判斷 def HTMLSearch(html, ranklist):try:flag = 0#找到所有tbody標(biāo)簽下的所有內(nèi)容,并且遍歷所有的兒子節(jié)點(diǎn)for tr in html.find("tbody").children:#添加判斷:獲得的內(nèi)容是否為標(biāo)簽Tag類型if isinstance(tr, bs4.element.Tag):#使用flag特判置頂?shù)那闆rif flag==0:rank = "置頂"#注意由于class屬性會(huì)和python中的關(guān)鍵字重名,因此需要變?yōu)閏lass_td02 = tr.find_all(class_=re.compile('td-02'))for i in td02:if isinstance(i, bs4.element.Tag):#trans得到的類型為列表trans = i.find_all("a")number = " "ranklist.append([rank, trans[0].string, number])flag = 1else:#排名信息在td標(biāo)簽下的class=td-01屬性中td01 = tr.find_all(class_=re.compile("td-01"))for i in td01:if isinstance(i, bs4.element.Tag):rank = i.string#熱搜內(nèi)容和搜索量在td標(biāo)簽下的class=td-02屬性中:內(nèi)容是a標(biāo)簽,搜索量是span標(biāo)簽td02 = tr.find_all(class_=re.compile("td-02"))for i in td02:name = i.find_all("a")column = i.find_all("span")#使用string獲取字符串信息不準(zhǔn)確,因?yàn)槲⒉┻€有一些熱搜標(biāo)題為含有表情的,因此使用了textranklist.append([rank, name[0].text, column[0].text])except:print("HTMLSearchError!")#打印排名 def Rankprint(ranklist, num):try:#先打印表頭,總長(zhǎng)為70個(gè)字符,其中{1}和{3}是變化的空格數(shù)量計(jì)算,默認(rèn)為:#排名*4,空格*3,名稱*50,空格*5,點(diǎn)擊量*8a = " "print("——————————————————————————————————————")print("{0}{1}{2}{3}{4}\n".format("排名", a*5, "熱搜內(nèi)容", a*45, "搜索量"+a*2))#使用flag來(lái)判斷是否輸出了置頂內(nèi)容flag = 0for i in range(num):if flag==0:print("{0}{1}{2}\n".format(ranklist[i][0], a*3, ranklist[i][1]))flag = 1else:#c是排名有一位、兩位的數(shù)字,用來(lái)糾正空格c = 7-len(ranklist[i][0])#根據(jù)內(nèi)容來(lái)隨時(shí)計(jì)算所要填充的空格數(shù)量bstr = ranklist[i][1]b = 62-length(ranklist[i][1])-len(ranklist[i][0])-cprint("{0}{1}{2}{3}{4:<8}".format(ranklist[i][0], a*c, ranklist[i][1], a*b, ranklist[i][2]))print("\n")except:print("RankPrintError!")#主函數(shù) def main():try:#微博熱搜的網(wǎng)站url = "https://s.weibo.com/top/summary?Refer=top_hot&topnav=1&wvr=6"#使用二維列表存儲(chǔ)每一條熱搜信息的rank信息和內(nèi)容rank = []text = getHTMLText(url)soup = HTMLTextconvert(text)HTMLSearch(soup, rank)Rankprint(rank, 51)except:print("SystemError!")return 0 main()

在所有可能發(fā)生錯(cuò)誤的部分都增加了報(bào)錯(cuò)機(jī)制,這樣程序就更加的具有適應(yīng)能力了!

?

總結(jié)

以上是生活随笔為你收集整理的Python爬虫与信息提取(五)爬虫实例:爬取新浪微博热搜排名的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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