用Python實現(xiàn)爬取百度熱搜信息
前言
何為爬蟲,其實就是利用計算機(jī)模擬人對網(wǎng)頁的操作
例如 模擬人類瀏覽購物網(wǎng)站
使用爬蟲前一定要看目標(biāo)網(wǎng)站可刑不可刑 :-)
可以在目標(biāo)網(wǎng)站添加/robots.txt 查看網(wǎng)頁具體信息
例如對天貓 可輸入 https://brita.tmall.com/robots.txt 進(jìn)行查看
User-agent 代表發(fā)送請求的對象
星號*代表任何搜索引擎
Disallow 代表不允許訪問的部分
/代表從根目錄開始
Allow代表允許訪問的部分
在本例中 我爬取的百度熱搜前30的新聞(本人原本打算爬取英雄聯(lián)盟主頁 數(shù)據(jù)中心 大亂斗勝率前五十的英雄信息 奈何不會實現(xiàn)延時爬取網(wǎng)頁的操作 無奈只能爬百度熱搜) 并且其大致信息放到Excel表格以及Flask網(wǎng)頁中實現(xiàn)數(shù)據(jù)可視化 感興趣的同學(xué)也可以對其它內(nèi)容進(jìn)行爬取
由于本人水平有限 本文章中的爬蟲都是比較基礎(chǔ)的東西
庫函數(shù)準(zhǔn)備
Python庫的安裝方法:
打開cmd命令提示符輸入pip install XXX(這個是你要裝的庫名稱)
關(guān)于這些庫的具體使用 可以接下來看我的操作
只需要簡單掌握幾個常用的函數(shù)即可
bs4
即BeautifulSoup
用來解析HTML網(wǎng)頁,提取指定數(shù)據(jù)的。
其中詳細(xì)的用法待會看我的演示。
re
正則表達(dá)式 用來匹配字符串中響應(yīng)的字串。
關(guān)于正則表達(dá)式 可以去看菜鳥教程 里邊講的很詳細(xì)
urllib
是一個Python自帶的HTTP請求庫,可以操作一系列URL。
xlwt/xlrt
用于寫入(write) / 讀取(read),Excel表中的數(shù)據(jù)。
flask
這個庫是用來只做一個簡單的Web框架即網(wǎng)站,用于數(shù)據(jù)的可視化。
其實本人對于數(shù)據(jù)可視化的掌握也很淺薄,只是簡單的將數(shù)據(jù)導(dǎo)入Web網(wǎng)頁中。
jinja2
這個庫的作用是為了實現(xiàn)在HTML網(wǎng)頁中的字符中插入自變量的功能。
后端: name="HQ" 前端: <p>{{name}}長得真帥!</p> 顯示: HQ長得真帥!
markupsafe
與Jinja共用 在渲染頁面時用于避免不可信的輸入,防止注入攻擊(雖然沒人會攻擊你....)
數(shù)據(jù)爬取
數(shù)據(jù)爬取 和 數(shù)據(jù)可視化 兩個py文件是分開的
數(shù)據(jù)爬取需要導(dǎo)入re bs4 urllib xlwt 四個庫文件
網(wǎng)頁爬取
使用一下的方法調(diào)用函數(shù)可以使函數(shù)調(diào)用關(guān)系更加清晰
if __name__=="__main__": #當(dāng)程序執(zhí)行時 調(diào)用一下函數(shù) main()
def askurl(url): head={ "User-Agent":'''Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.55''' } #用戶代理 告訴服務(wù)器我只是一個普普通通的瀏覽器 requset=urllib.request.Request(url) #發(fā)送請求 response=urllib.request.urlopen(requset) #響應(yīng)的為一個request對象 #通過read()轉(zhuǎn)化為 bytes類型字符串 #再通過decode()轉(zhuǎn)化為 str類型的字符串 #接受響應(yīng) html=response.read().decode('utf-8') 將抓取到的網(wǎng)頁存入文檔中 方便觀察 path=r"C:\Users\XXX\Desktop\Python\text.txt" #這里在字符串前加入r 防止字符串中的\發(fā)生轉(zhuǎn)義 f=open(r"path",'w',encoding='utf-8') f.write(html) f.close() #這樣在txt文件中就可以查看網(wǎng)頁的源碼 return html
headers的值可以在網(wǎng)頁中按F12
然后點擊網(wǎng)絡(luò)變化 對于任意一個請求標(biāo)頭 下拉到最下方即為 user-agent 代理信息
值得注意的是 請求中如果不設(shè)置headers 則服務(wù)器會返回一個418的狀態(tài)碼
代表服務(wù)器識別出來你是一個爬蟲 并且表示:“ I'm a teapot ”
表明服務(wù)器拒絕沖煮咖啡,因為它永遠(yuǎn)是一個茶壺(這是一個梗)
數(shù)據(jù)解析
將抓取的txt文件后綴改為html后打開即為一個本地的網(wǎng)頁
如果在vscode中因為行過長而產(chǎn)生報錯 可以參考以下博客
打開后的網(wǎng)頁如圖所示
使用這個功能查看需要爬取信息的位置
在本項目中 我們抓取目標(biāo)信息的標(biāo)題 內(nèi)容 熱度 以及鏈接
我們可以發(fā)現(xiàn) 我們需要的信息全部在class為以下類型的表中
于是我們用Beautifulsoup對網(wǎng)頁進(jìn)行解析
def getData(html): datalist=[] soup=BeautifulSoup(html,"html.parser") #定義一個解析對象 #soup.find_all(a,b) 其中a為標(biāo)簽的類型 class_ 對div的class進(jìn)行匹配 #返回的是所有class為category-wrap_iQLoo horizontal_1eKyQ的列表 for item in soup.find_all('div',class_="category-wrap_iQLoo horizontal_1eKyQ"): item=str(item) #將列表中每一個子標(biāo)簽轉(zhuǎn)換為字符串用于re匹配
接下來對每一個item進(jìn)行re匹配
首先使用re.compile()創(chuàng)建匹配規(guī)則 然后用findall進(jìn)行匹配
匹配規(guī)則的創(chuàng)建方式為在HTML文件中查看目標(biāo)信息前后的特殊字符
而(.*?)即為要匹配的字符串 其中*后加?代表非貪婪匹配
例如
標(biāo)題前后信息即為ellipsis">和</div> <div cla
其它同理
#匹配規(guī)則 #鏈接 findlink=re.compile(r' href="(.*?)" rel="external nofollow" target="_blank') #標(biāo)題 findtitle=re.compile(r'ellipsis"> (.*?) </div> <div cla') #內(nèi)容 findcontent1=re.compile(r'ellipsis_DupbZ"> (.*?) <a class=') findcontent2=re.compile(r'small_Uvkd3"> (.*?) <a class=') #熱度 findnumber=re.compile(r'ex_1Bl1a"> (.*?) </div>')
而內(nèi)容部分 我在后續(xù)運行的時候發(fā)現(xiàn)報錯 原因是
部分內(nèi)容前綴為'ellipsis_DupbZ"> 部分內(nèi)容前綴為small_Uvkd3">
因此我編寫了兩種匹配方式
具體代碼如下
def getData(html): datalist=[] soup=BeautifulSoup(html,"html.parser") #定義一個解析對象 #soup.find_all(a,b) 其中a為標(biāo)簽的類型 class_ 對div的class進(jìn)行匹配 #返回的是所有class為category-wrap_iQLoo horizontal_1eKyQ的列表 for item in soup.find_all('div',class_="category-wrap_iQLoo horizontal_1eKyQ"): item=str(item) #將列表中每一個子標(biāo)簽轉(zhuǎn)換為字符串用于re匹配 data=[] #標(biāo)題 title=re.findall(findtitle,item)[0] #簡介 #判斷是否對第一種匹配 如果不是的話返回為空列表 此時應(yīng)采用第二種匹配 if (len(re.findall(findcontent1,item))!=0): content=re.findall(findcontent1,item)[0] else: content=re.findall(findcontent2,item)[0] #熱度 number=re.findall(findnumber,item)[0] #鏈接 link=re.findall(findlink,item)[0] #將數(shù)據(jù)存入數(shù)組 data.append(title) data.append(number) data.append(content) data.append(link) datalist.append(data) print(datalist) return datalist
數(shù)據(jù)保存
def Savedata(datalist): #存入數(shù)據(jù)的目標(biāo)路徑 path=r'C:\Users\XXX\Desktop\Python\爬蟲\data.xls' workbook=xlwt.Workbook(encoding='utf-8') #創(chuàng)建工作表對象 worksheet=workbook.add_sheet('sheet1') #創(chuàng)建表單 col=("標(biāo)題","熱度","內(nèi)容","鏈接") #定義表含有的屬性 for i in range(4): worksheet.write(0,i,col[i]) #write(i,j,value) 向 表單的 [i][j] 位置寫入value for i in range(30): for j in range(4): worksheet.write(i+1,j,datalist[i][j]) #將excel表保存 workbook.save(path)
總結(jié)
到此這篇關(guān)于用Python實現(xiàn)爬取百度熱搜信息的文章就介紹到這了,更多相關(guān)Python爬取百度熱搜內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python中from module import * 的一個坑
from module import *把module中的成員全部導(dǎo)到了當(dāng)前的global namespace,訪問起來就比較方便了。當(dāng)然,python style一般不建議這么做,因為可能引起name conflict。2014-07-07Python threading.local代碼實例及原理解析
這篇文章主要介紹了Python threading.local代碼實例及原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03使用python將mysql數(shù)據(jù)庫的數(shù)據(jù)轉(zhuǎn)換為json數(shù)據(jù)的方法
這篇文章主要介紹了使用python將mysql數(shù)據(jù)庫的數(shù)據(jù)轉(zhuǎn)換為json數(shù)據(jù)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07