在上一篇爬取貼吧頁面HTML文件的基礎上:https://blog.csdn.net/lfy905805357/article/details/93539602
進一步簡單解析爬取的頁面,抽取出HTML裏面的各種帖子主題
一、題目
請編寫程序實現如下功能:
1、提示用戶需要爬取的百度貼吧的主題
2、爬取對應主題的百度貼吧第一頁上所有的帖子標題並逐行打印,效果如下:
二、問題規律分析
初步構思可以利用XPath來解析定位相應的主題例如
使用Chrome打開相關網頁,在對應的元素上點擊右鍵選擇” 檢查”,可以查看到網頁元素對應的html源碼。
在對應的html源碼上點擊右鍵進行選擇:
然後我們找到對應的貼吧主題對應的a標籤複製其XPath找找規律
我找了好幾個帖子的主題的XPath如下
//*[@id="thread_top_list"]/li[1]/div/div[2]/div/div[1]/a
//*[@id="thread_list"]/li[2]/div/div[2]/div[1]/div[1]/a
//*[@id="thread_list"]/li[3]/div/div[2]/div[1]/div[1]/a
//*[@id="thread_list"]/li[6]/div/div[2]/div[1]/div[1]/a
通過觀察可以發現,其中的共同點不是很歸一,還是有好幾處不太一樣,這樣就不方便統一一個獲取方式將所有的主題獲取到,再通過進一步分析,所有的包含主題的a標籤都歸屬一個類“j_th_tit ”
那我們可以直接這個類屬性直接獲取所有包含主題的a標籤,這樣就解決問題了
三、源碼
# -*- coding: utf-8 -*-
"""
Created on Tue Jun 25 14:23:42 2019
@author: UnderMask
"""
#爬取百度貼吧指定搜索主題的所有貼吧標題
import datetime
import requests
from lxml import etree
def climb(theme,start_page,end_page):#給定貼吧搜索主題、爬取起始頁碼、爬取終止頁碼
url="https://tieba.baidu.com/f?"#百度貼吧未給定搜索主題時的網頁URL前綴
for i in range(start_page,end_page+1):#從起始頁碼爬取到終止頁碼
offset=(i-1)*50#可用看出百度貼吧的頁面規律,一個頁碼pn的值偏移量爲50(第一頁爲0,第二頁的pn=50,第三頁的pn=100...)
response=requests.get(url,params={"kw":theme,"pn":str(offset)})#給定請求時的參數、搜索主題,跟頁碼pn的偏移量值
response.encoding="utf-8"#設定utf-8編碼方式,防止亂碼
print(response.url)
print("----------------------第"+str(i)+"頁----------------------")
html = etree.HTML(response.text)#使用etree.HTML將字符串轉換爲標準的HTML文檔
res = etree.tostring(html)#按字符串序列化html文檔
html = etree.HTML(str(res))#使用etree.HTML將字符串轉換爲標準的HTML文檔
result = html.xpath('//*[@class="j_th_tit "]/text()')#由於包含主題的a標籤都具有class="j_th_tit "的類屬性,直接通過該特徵檢索
for t in result:
print(t)
if __name__=="__main__":
theme=input("請輸入想要爬取的百度貼吧主題:")
start_page=int(input("請輸入想要爬取的起始頁碼:"))
end_page=int(input("請輸入想要爬取的終止頁碼:"))
start_time=datetime.datetime.now()
print("[" + start_time.strftime('%Y-%m-%d %H:%M:%S') + "]>>>"+"爬取開始!")
climb(theme,start_page,end_page)
end_time=datetime.datetime.now()
print("[" + end_time.strftime('%Y-%m-%d %H:%M:%S') + "]>>>"+"爬取結束!")
print("總用時:",(end_time-start_time))
四、運行效果