Python爬取百度實時熱點排行榜


今天爬取的百度的實時熱點排行榜

按照慣例,先下載網站的內容到本地:

1 def downhtml():
2     url = 'http://top.baidu.com/buzz?b=1&fr=20811'
3     headers = {'User-Agent':'Mozilla/5.0'}
4     r = requests.get('url',headers=headers)
5     with open('C:/Code/info_baidu.html','wb') as f:
6         f.write(r.content)

因為我習慣把網頁整個抓到本地再來分析數據,所以會有這一步,后面會貼直接抓取並分析的代碼。


開始分析數據:

我想抓取的排名,關鍵詞和搜索指數這三個值。

打開網頁源代碼:

發現每個標題的各個元素是一個個td被包裝在一個tr標簽里面,每一個標題都是一個tr(這里注意前三個標題的tr標簽是有class=‘hideline’,而后面的則沒有)

 

排名 :第一個td    class=''first'

關鍵詞:第二個td    cass = 'keyword'

搜索指數:最后一個td   class = 'last'

確定了我所需要的數據的位置了之后,可以開始寫代碼了。

寫一個把打開本地html並返回給BeautifulSoup調用的函數:

def send_html():#把本地的html文件調給get_pages的BeautifulSoup
    path = 'C:/Code/info_baidu.html'
    htmlfile= open(path,'r')
    htmlhandle = htmlfile.read()
    return htmlhandle

這樣,我就可以在下面的直接用本地html來測試,而不用每次都去請求百度的服務器了。

def get_pages(html):
    soup = BeautifulSoup(html,'html.parser')
    all_topics=soup.find_all('tr')[1:]#切片

因為第一個tr裝的是這些東西

<tr>
        <th width="50" class="first">排名</th>
        <th>關鍵詞</th>
        <th width="30%" class="tc">相關鏈接</th>
        <th width="20%" class="last">搜索指數</th>
    </tr>

 

並不是排名第一的標題,所以我用切片把它過濾掉了。

然后開始挨個賦值:

def get_pages(html):
    soup = BeautifulSoup(html,'html.parser')
    all_topics=soup.find_all('tr')[1:]
    for each_topic in all_topics:
        #print(each_topic)
        topic_times = each_topic.find('td',class_='last').get_text()#搜索指數
        topic_rank = each_topic.find('td',class_='first').get_text()#排名
        topic_name = each_topic.find('td',class_='keyword').get_text()#標題目
        print('排名:{},標題:{},熱度:{}'.format(topic_rank,topic_name,topic_times))

這樣按道理來說應該是可以輸出了,但百度還是想給我一點難度。

這里出現幾個問題,

1:AttributeError: 'NoneType' object has no attribute 'get_text'

2:輸出的格式

3:只有一個值

按照慣例,第一個問題應該是里面多了一些不是Tag的類型,所以就來測試一下:

def get_pages(html):
    soup = BeautifulSoup(html,'html.parser')
    all_topics=soup.find_all('tr')[1:]
    for each_topic in all_topics:
        #print(each_topic)
        topic_times = each_topic.find('td',class_='last')#搜索指數
        print(type(topic_times))

輸出如下:

我們可以發現前幾個值都參雜了NoneType(我去源代碼看了一下,並不知道是什么導致的,等以后我知道了,再回來!)

因此,我們只要把NoneType給過濾掉就行。

def get_pages(html):
    soup = BeautifulSoup(html,'html.parser')
    all_topics=soup.find_all('tr')[1:]
    for each_topic in all_topics:
        #print(each_topic)
        topic_times = each_topic.find('td',class_='last')#搜索指數
        topic_rank = each_topic.find('td',class_='first')#排名
        topic_name = each_topic.find('td',class_='keyword')#標題目
        # print('排名:{},標題:{},熱度:{}'.format(topic_rank,topic_name,topic_times))
        if topic_rank != None and topic_name!=None and topic_times!=None:
            topic_rank = each_topic.find('td',class_='first').get_text()
            topic_name = each_topic.find('td',class_='keyword').get_text()
            topic_times = each_topic.find('td',class_='last').get_text()
            print('排名:{},標題:{},熱度:{}'.format(topic_rank,topic_name,topic_times))

輸出如下:

這樣就解決了第一個問題,發現可以輸出了,連第三個問題也解決了。

但第二個問題還在,這shit一般的格式讓我很難受,導致這樣的原因我猜是get_text時把一些空格符和換行符也一起輸出了。

所以用replace()就應該可以解決了。

if topic_rank != None and topic_name!=None and topic_times!=None:
            topic_rank = each_topic.find('td',class_='first').get_text().replace(' ','').replace('\n','')
            topic_name = each_topic.find('td',class_='keyword').get_text().replace(' ','').replace('\n','')
            topic_times = each_topic.find('td',class_='last').get_text().replace(' ','').replace('\n','')
            print('排名:{},標題:{},熱度:{}'.format(topic_rank,topic_name,topic_times))

輸出如下:

哦吼,這樣感覺就不錯了。

但強迫症患者感覺還是很難受啊,這個熱度(搜索指數)的格式也太亂了。

經過一番搜索,網友的力量還是很強大的啊哈哈哈,馬上就有辦法了。

if topic_rank != None and topic_name!=None and topic_times!=None:
            topic_rank = each_topic.find('td',class_='first').get_text().replace(' ','').replace('\n','')
            topic_name = each_topic.find('td',class_='keyword').get_text().replace(' ','').replace('\n','')
            topic_times = each_topic.find('td',class_='last').get_text().replace(' ','').replace('\n','')
            #print('排名:{},標題:{},熱度:{}'.format(topic_rank,topic_name,topic_times))
            tplt = "排名:{0:^4}\t標題:{1:{3}^15}\t熱度:{2:^7}"
            print(tplt.format(topic_rank,topic_name,topic_times,chr(12288)))    

輸出如下:

本強迫症患者終於滿足了哈哈。

附上總代碼:

 1 import requests
 2 from bs4 import BeautifulSoup
 3 import bs4
 4 
 5 
 6 def send_html():#把本地的html文件調給get_pages的BeautifulSoup
 7     path = 'C:/Code/info_baidu.html'
 8     htmlfile= open(path,'r')
 9     htmlhandle = htmlfile.read()
10     return htmlhandle
11 
12 def get_pages(html):
13     soup = BeautifulSoup(html,'html.parser')
14     all_topics=soup.find_all('tr')[1:]
15     for each_topic in all_topics:
16         #print(each_topic)
17         topic_times = each_topic.find('td',class_='last')#搜索指數
18         topic_rank = each_topic.find('td',class_='first')#排名
19         topic_name = each_topic.find('td',class_='keyword')#標題目
20         if topic_rank != None and topic_name!=None and topic_times!=None:
21             topic_rank = each_topic.find('td',class_='first').get_text().replace(' ','').replace('\n','')
22             topic_name = each_topic.find('td',class_='keyword').get_text().replace(' ','').replace('\n','')
23             topic_times = each_topic.find('td',class_='last').get_text().replace(' ','').replace('\n','')
24             #print('排名:{},標題:{},熱度:{}'.format(topic_rank,topic_name,topic_times))
25             tplt = "排名:{0:^4}\t標題:{1:{3}^15}\t熱度:{2:^7}"
26             print(tplt.format(topic_rank,topic_name,topic_times,chr(12288)))    
27 
28 if __name__ =='__main__':
29     get_pages(send_html())

還有直接爬取不用下載網頁的總代碼:

 

 1 import requests
 2 from bs4 import BeautifulSoup
 3 import bs4
 4 
 5 def get_html(url,headers):
 6     r = requests.get(url,headers=headers)
 7     r.encoding = r.apparent_encoding 
 8     return r.text
 9 
10 
11 def get_pages(html):
12     soup = BeautifulSoup(html,'html.parser')
13     all_topics=soup.find_all('tr')[1:]
14     for each_topic in all_topics:
15         #print(each_topic)
16         topic_times = each_topic.find('td',class_='last')#搜索指數
17         topic_rank = each_topic.find('td',class_='first')#排名
18         topic_name = each_topic.find('td',class_='keyword')#標題目
19         if topic_rank != None and topic_name!=None and topic_times!=None:
20             topic_rank = each_topic.find('td',class_='first').get_text().replace(' ','').replace('\n','')
21             topic_name = each_topic.find('td',class_='keyword').get_text().replace(' ','').replace('\n','')
22             topic_times = each_topic.find('td',class_='last').get_text().replace(' ','').replace('\n','')
23             #print('排名:{},標題:{},熱度:{}'.format(topic_rank,topic_name,topic_times))
24             tplt = "排名:{0:^4}\t標題:{1:{3}^15}\t熱度:{2:^8}"
25             print(tplt.format(topic_rank,topic_name,topic_times,chr(12288)))    
26 
27 def main():
28     url = 'http://top.baidu.com/buzz?b=1&fr=20811'
29     headers= {'User-Agent':'Mozilla/5.0'}
30     html = get_html(url,headers)
31     get_pages(html)
32 
33 if __name__=='__main__':
34     main()

 

好了。完成任務,生活愉快!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM