




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
網(wǎng)絡同濟大學計算機基礎教研室第5章網(wǎng)絡爬蟲與信息提取
5.1爬蟲基本原理及獲取數(shù)據(jù)數(shù)據(jù)表示計算可視化特征分析1.爬蟲原理及網(wǎng)頁構造2.引例及Requests庫3.問題及限制4.實例網(wǎng)絡連接自助售貨機:選擇商品
投入硬幣/紙幣/掃碼
彈出相應的商品瀏覽網(wǎng)頁:在瀏覽器中輸入一個網(wǎng)址后敲擊回車,看到網(wǎng)站的頁面信息。即:瀏覽器請求了網(wǎng)站的服務器,獲取到網(wǎng)絡資源。爬蟲:模擬瀏覽器發(fā)送請求,獲得html代碼。html包括標簽和文字,再從中提取想要的信息。電腦服務器request(請求頭和消息體)response(HTML文件)(2)相應的服務器(自助售貨機)會返回相應的HTML文件(相應的商品)作為Response(1)本機電腦(購買者)帶著請求頭和消息體(硬幣和商品需求)向服務器(自助售貨機)發(fā)起一次Request請求(購買)爬蟲原理網(wǎng)絡爬蟲(WebSpider)如果把互聯(lián)網(wǎng)看作一張大網(wǎng),那么爬蟲就是在大網(wǎng)上爬來爬去的蜘蛛,碰到想要的食物就把他抓取出來。爬蟲原理網(wǎng)絡爬蟲就是一種按照一定的規(guī)則,根據(jù)網(wǎng)頁的地址(即URL)自動地抓取網(wǎng)頁信息的程序或者腳本。網(wǎng)絡連接需要:爬蟲需要:(1)電腦的Request請求(2)服務器端的Response回應(1)模擬電腦對服務器發(fā)起Request請求(2)接收服務器端的Response的內(nèi)容,并且解析提取所需信息引例1——爬取百度新聞頁面
()#引入Requests庫importrequests#發(fā)起GET請求response=requests.get('/')#輸出響應內(nèi)容print(response.text)URL地址網(wǎng)頁html代碼Chrome瀏覽器輸入URL地址“”打開頁面在網(wǎng)頁處單擊右鍵,選擇“檢查”,打開開發(fā)者工具Elements選項卡包含了網(wǎng)頁經(jīng)JavaScript處理的最終HTML代碼。Network選項卡中包含了瀏覽器收到的網(wǎng)頁源代碼。(IE中“查看源文件”或Firefox中“查看頁面源代碼”)HTML代碼超文本標記語言JavaScript語言交互和動畫效果經(jīng)js處理的HTML代碼CSS樣式層疊樣式表<pclass="title"></p>html源代碼由很多尖括號構成的標簽組織而成標簽樹標簽之間存在上下游關系文件CSS樣式層疊樣式表經(jīng)js處理的HTML代碼Tips:Chrome中審查元素與網(wǎng)頁源代碼區(qū)別審查元素看到實時性的內(nèi)容(經(jīng)過js的修改),即最終的html代碼定位網(wǎng)頁元素、及時調(diào)試、修改、定位、追蹤檢查、查看嵌套、修改樣式和查看js動態(tài)輸出信息。網(wǎng)頁源代碼看到最開始瀏覽器收到HTTP響應內(nèi)容,查看源代碼只是把網(wǎng)頁輸出的源代碼直接打開,既不能動態(tài)變化,也不能修改。引例2-爬取頁面的新聞標題和鏈接爬蟲基本流程網(wǎng)絡爬蟲就是要模擬用戶使用瀏覽器訪問網(wǎng)頁的過程,即先模擬電腦對服務器發(fā)起Request請求,再接受服務器端的Response響應內(nèi)容,根據(jù)需要進行解析和提取,并保存所需的信息。發(fā)起請求獲取響應內(nèi)容解析內(nèi)容保存數(shù)據(jù)電腦服務器request(請求頭和消息體)response(HTML文件)爬蟲基本流程1.發(fā)起請求:向目標站點發(fā)送一個Request(可以包含額外的headers等信息),即發(fā)起請求,然后等待服務器響應。相當于瀏覽器作為一個瀏覽的客戶端,向服務器端發(fā)送了一次請求(我們打開瀏覽器并輸入網(wǎng)址,然后點擊回車)。電腦服務器Request(請求頭和消息體)爬蟲基本流程2.獲取響應內(nèi)容:如果服務器能正常響應,我們會得到一個Response,即獲取到的內(nèi)容,類型可能有HTML、Json字符串、二進制數(shù)據(jù)(圖片,視頻等)等。相當于服務器接收客戶端的請求,進而將網(wǎng)頁HTML文件發(fā)送給瀏覽器。電腦服務器Response爬蟲基本流程3.解析內(nèi)容:得到的內(nèi)容也許是HTML,可使用正則表達式,網(wǎng)頁解析庫(如BeautifulSoup)進行解析也許是Json,可直接轉(zhuǎn)為Json對象解析也許是二進制數(shù)據(jù),可進行保存或者進一步處理相當于瀏覽器把服務器端的文件獲取到本地,再進行解釋并且展現(xiàn)出來。爬蟲基本流程4.保存數(shù)據(jù):保存的方式把數(shù)據(jù)存為文本把數(shù)據(jù)保存到數(shù)據(jù)庫把數(shù)據(jù)保存為jpg、mp4等格式…相當于瀏覽網(wǎng)頁時,下載網(wǎng)頁上的圖片或者視頻爬蟲基本流程爬蟲就是獲取網(wǎng)頁并提取和保存信息的自動化程序在快速獲取大量數(shù)據(jù)時,通過爬蟲程序來自動抓取并進行異常處理、錯誤重試等等操作,確保爬蟲保持高效運行。Urllib.Request/Requests庫Python3中可使用urllib.request和requests進行網(wǎng)頁爬取urllib庫:python內(nèi)置,無需額外安裝,但使用不夠方便。requests庫:第三方庫,需安裝。基于urllib3,采用Apache2Licensed開源協(xié)議的HTTP庫。requests庫簡單易用,比urllib更加方便。課內(nèi)使用requests庫獲取網(wǎng)頁的HTML信息,安裝方法:IDLE:在cmd命令行中
pipinstallrequestsAnaconda:在prompt中condainstallrequests檢測:在交互式環(huán)境(IDLE、Spyder等)中輸入importrequests不報錯,說明requests模塊成功安裝引例擴展(1).為了使用requests,需要首先引入requests庫:(2).使用requests來發(fā)送http請求,如get請求:(3).獲得的Response對象r,即http請求的響應結(jié)果。
顯示Response對象r的一些屬性,如:importrequestsr=requests.get('/')#檢測r的類型print(type(r))#獲取請求信息的urlprint(r.url)#請求的狀態(tài)碼print(r.status_code)Responseresponse對象包含了三部分主要信息響應狀態(tài)響應頭(ResponseHeader)包括內(nèi)容類型,長度,服務器信息,設置Cookie等信息。響應體(Responsebody)主要包含請求資源的內(nèi)容,如網(wǎng)頁的HTML代碼、圖片的二進制數(shù)據(jù)等。200404502301成功找不到頁面服務器錯誤跳轉(zhuǎn)頁面r.status_coder.headersr.textresponsestatus_codeheadersbodyISO-8859-1UTF-8亂碼?#顯示Response對象的編碼方式print(r.encoding)#顯示Response對象的文本編碼print(r.apparent_encoding)#修改編碼方式后重新顯示r.encoding=r.apparent_encodingprint(r.text)從headers猜測response對象的編碼方式。若header中不存在charset,則認為是ISO-8859-1r.text根據(jù)r.encoding顯示網(wǎng)頁內(nèi)容根據(jù)網(wǎng)頁內(nèi)容分析出的編碼方式。原則來說更加準確。Response對象的主要屬性屬
性說
明r.status_codehttp請求的返回狀態(tài),200表示成功,其他(如404)表示失敗r.texthttp響應內(nèi)容的字符串形式,即url對應的頁面內(nèi)容r.contenthttp響應內(nèi)容的二進制形式,即url對應內(nèi)容的二進制形式r.encoding從httpheader中猜測的響應內(nèi)容編碼方式r.apparent_encoding從內(nèi)容中分析出的響應內(nèi)容編碼方式,備選編碼方式bytes型的原始二進制數(shù)據(jù)處理過的Unicode型的數(shù)據(jù)得到的內(nèi)容網(wǎng)頁文本HTML文檔、Json格式文本等圖片、音頻、視頻二進制文件,保存為相應的格式其他r=requests.get('/img/baidu_jgylogo3.gif')print(r.content)
#二進制文件使用content#保存圖片withopen('logo.gif','wb')asf:f.write(r.content)print('Ok')Requests庫的異常類型異常說明ConnectionError網(wǎng)絡連接出現(xiàn)錯誤,如DNS查詢失敗、拒絕連接HTTPErrorHTTP協(xié)議層面出現(xiàn)錯誤URLRequiredURL缺失造成的異常TooManyRedirects超過最大重定向次數(shù)產(chǎn)生異常ConnectTimeout連接遠程服務器超時異常Timeout請求URL超時,產(chǎn)生超時錯誤超時設置利用timeout變量來配置最大請求時間,如果在timeout時間內(nèi)請求內(nèi)容沒有返回,將產(chǎn)生一個timeout的異常。importrequestsresp=requests.get('',timeout=0.5)print(resp.status_code)如果在指定時間內(nèi)沒有返回,就會拋出timeout異常。如果遠端服務器很慢,可以傳入一個None作為timeout值,使得requests永遠等待。timeout僅對連接過程有效:只限制請求的時間,與響應體的下載無關。即:當返回的response包含很大內(nèi)容,下載需要一定時間,與timeout沒有關系。連接、讀取超時requests.get('http://',timeout=(6.005,0.01))分別指定連接和讀取的超時時間,服務器在指定時間沒有應答,拋出requests.exceptions.ConnectTimeout/ReadTimeout-timeout=([連接超時時間],[讀取超時時間])-連接:客戶端連接服務器并發(fā)送http請求-讀?。嚎蛻舳说却掌靼l(fā)送第一個字節(jié)之前的時間請求不成功(狀態(tài)碼)bad_r=requests.get('/status/404')bad_r.raise_for_status()如果HTTP請求返回了不成功的狀態(tài)碼(4XX客戶端錯誤,或者5XX服務端錯誤),Response.raise_for_status()拋出
requests.exceptions.HTTPError
Requests庫的異常處理importrequestsfromrequests.exceptionsimportConnectTimeout,RequestExceptiontry:response=requests.get('',timeout=0.005)print(response.status_code)exceptConnectTimeout: #超時異常print('timeout')exceptRequestException: #請求異常print('reqerror')異常處理當你不確定會發(fā)生什么錯誤時,盡量使用try...except來捕獲異常攜程爬取importrequestsurl="/tour/detail/p12906212s2.html#ctm_ref=va_youxue_s2_lst_p1_l2_1_txt"try:r=requests.get(url,timeout=0.5)
r.raise_for_status()
print(r.text[:500])except:print("爬取失敗")爬取網(wǎng)頁的通用代碼框架通用代碼框架可以有效處理和避免訪問和爬取網(wǎng)頁過程中可能出現(xiàn)的錯誤,提高訪問和爬取的效率。importrequests #加載Requests庫defget_html(url): #定義get_html函數(shù)
try:r=requests.get(url,timeout=40) #設定get函數(shù)參數(shù),超時限制40sr.raise_for_status()#有效判斷網(wǎng)絡連接狀態(tài),錯誤將捕獲異常
r.encoding=r.apparent_encoding#設置編碼格式
returnr.text #返回網(wǎng)頁文本內(nèi)容
except:return"產(chǎn)生異常" #返回異常提示if__name__==“_main_”: #直接運行時(非以模塊導入)
url="" #給url賦值
print(get_html(url)) #打印函數(shù)內(nèi)容HTTP基本知識URL:統(tǒng)一資源定位符。HTTP協(xié)議一般采用url作為定位網(wǎng)絡資源的標識超文本:HyperTexthttp://[host]:[port]/[path]
/info/1032/22142.htm合法的internet主機,域名或ip地址端口號,省略時默認端口號為80資源在該主機或ip地址服務器上所包含的內(nèi)部路徑HTTP基本知識HTTP(HyperTextTransferProtocol)超文本傳輸協(xié)議。用于將超文本數(shù)據(jù)從網(wǎng)絡傳輸?shù)奖镜貫g覽器而制定的傳送協(xié)議保證高效而準確地傳送超文本文檔基于請求與響應模式的無狀態(tài)的應用層協(xié)議。HTTPS(HyperTextTransferProtocoloverSecureSocketLayer)以SSL為安全基礎的HTTP協(xié)議用戶發(fā)起請求,服務器做相關響應第一次請求跟第二次請求之間,并沒有相關的關聯(lián)協(xié)議工作在TCP協(xié)議之上爬蟲基本流程1.發(fā)起請求2.獲取響應內(nèi)容電腦服務器Request(請求頭和消息體)Response(HTML文件)NetworkNameMethodStatusTypeInitiatorSizeTimeWaterfallNetworkNameMethodStatusTypeInitiatorSizeTimeWaterfallGeneralResponseHeadersRequestHeadersRequestURLRequestMethodStatusCodeRemoteAddressReferrerPolicy請求請求是由客戶端向服務端發(fā)出的,包括:requestmethod請求方式;requestURL請求網(wǎng)址;requestheader請求頭;requestBody請求體瀏覽器發(fā)信息給該網(wǎng)址所在服務器,即向服務器提出請求。請求方式主要有GET、POST、HEAD、PUT、DELETE。GET請求的請求參數(shù)會顯示在URL鏈接的后面。如用百度搜索“同濟”,請求的URL鏈接變?yōu)椋?s?wd=同濟POST請求的請求參數(shù)會存放在Request內(nèi),并不會出現(xiàn)在URL鏈接的后面。如登錄信息。請求請求URL統(tǒng)一資源定位符,即網(wǎng)址。URL可以確定一張網(wǎng)絡圖片、一個音頻、一個網(wǎng)頁文檔等,其包含的信息指出了文件的位置以及瀏覽器如何處理它。請求頭(Headers)包含請求時的頭部信息,例如User-Agent(指定瀏覽器的請求頭),Cookies、Host等。請求體額外攜帶的數(shù)據(jù),例如登錄表單提交的登錄信息HTTP操作方法方法說明GET向特定資源發(fā)起請求,請求頁面,返回頁面內(nèi)容HEAD獲取html網(wǎng)頁頭(類似于GET,但不返回網(wǎng)頁具體內(nèi)容)POST向html提交數(shù)據(jù)進行處理請求(如提交表單或上傳文件),數(shù)據(jù)包含在請求體中PUT從客戶端向服務器傳送的數(shù)據(jù)取代指定文檔中的內(nèi)容PATCH提交局部修改請求DELETE請求服務器刪除指定的頁面OPTIONS允許客戶端查看服務器的性能HTTP協(xié)議,通過URL對資源做定位,通過常用的方法,對資源進行管理,每一次操作都是獨立無狀態(tài)的。在HTTP協(xié)議的世界里,網(wǎng)絡通道跟服務器都是黑盒子,能看到的就是url鏈接以及對url鏈接的相關操作。Requests對象的方法方
法解
釋requests.request()構造一個請求,支持以下各種方法requests.get()獲取html的主要方法,對應http協(xié)議getrequests.head()獲取html頭部信息requests.post()向html網(wǎng)頁提交post請求requests.put()向html網(wǎng)頁提交put請求requests.patch()向html提交局部修改的請求requests.delete()向html提交刪除請求GET和POST是表單提交數(shù)據(jù)的兩種基本方式GET是從服務器上獲取數(shù)據(jù),POST是向服務器傳送數(shù)據(jù)GET請求數(shù)據(jù)通過域名后綴url傳送,用戶可見,不安全POST請求數(shù)據(jù)通過在請求報文正文里傳輸,相對比較安全Http定義了與服務器交互的不同方法,最基本的方法有4種:GET,POST,PUT,DELETE。一個URL地址,它用于描述一個網(wǎng)絡上的資源。而HTTP中的GET,POST,PUT,DELETE就對應著對這個資源的查,改,增,刪4個操作。GET一般用于獲取/查詢資源信息,而POST一般用于更新資源信息。request方法requests.request(method,url,**kwargs)請求方式,分別對應get等7種方法頁面鏈接控制訪問參數(shù)(13個)params:增加到url中的參數(shù)data:向服務器提供或提交資源時使用json:作為內(nèi)容部分向服務器提交json數(shù)據(jù)headers:向某url訪問時發(fā)起的http的頭字段cookies:從http協(xié)議中解析cookieauth:支持http認證功能files:向服務器傳輸文件使用timeout:設定的超時時間proxies:設定訪問代理服務器allow_redirects:是否允許對url進行重定向stream:對獲取的內(nèi)容是否進行立即下載verify:認證ssl證書
cert:本地ssl證書路徑'GET''HEAD''POST''PUT''PATCH''DELETE''OPTIONS'其他方法的具體形式requests.get(url,params=None,**kwargs)requests.head(url,**kwargs)requests.post(url,data=None,json=None,**kwargs)requests.put(url,data=None,**kwargs)requests.patch(url,data=None,**kwargs)requests.delete(url,**kwargs)r=requests.get("/get?name=Sharon&age=10")Get方法基本GET請求importrequestsr=requests.get('/get')print(r.text)requests.get(url,params=None,**kwargs)獲取html網(wǎng)頁內(nèi)容,返回一個response對象擬爬取的網(wǎng)站地址url中的額外參數(shù),字典或者字節(jié)序列,作為參數(shù)增加到url中控制訪問參數(shù)(12個)在get請求中,經(jīng)常使用params關鍵字,以一個字典來傳遞這些參數(shù)。將一些鍵值對以?key1=value1&key2=value2的模式增加到url中。Get方法帶參數(shù)的GET請求importrequestsdata={'name':'Sharon','age':10}r=requests.get('/get',params=data)print(r.url)requests.get(url,params=None,**kwargs)獲取html網(wǎng)頁內(nèi)容,返回一個response對象等價于:r=requests.get("/get?name=Sharon&age=10")#通過params,將data鍵值對增加到url添加headers以防有些網(wǎng)站禁止爬蟲訪問,添加瀏覽器的User-Agent信息importrequestsheaders={'User-Agent':"Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/74.0.3729.108Safari/537.36"}r=requests.get('',headers=headers)print(r.text)瀏覽器
檢查/審查元素network點擊鏈接Headers信息importrequestsr=requests.get("/get")print(r.request.headers['User-Agent'])headers={'User-Agent':'Sharon'}r=requests.get("/get",headers=headers)print(r.request.headers)在請求中指定請求代理:User-Agent:向訪問網(wǎng)站提供你所使用的瀏覽器類型及版本、操作系統(tǒng)及版本、瀏覽器內(nèi)核、等信息的標識。知乎頁面importrequestsr=requests.get("/explore")print(r.text)importrequestsheaders={'User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/81.0.4044.122Safari/537.36'}r=requests.get("/explore",headers=headers)print(r.text)/robots.txt傳遞關鍵字爬取百度新聞搜索keyword=input("inputkeyword:")url="/ns"kv={"word":keyword}headers={"User-Agent":"Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/63.0.3239.84Safari/537.36"}r=requests.get(url,timeout=30,params=kv,headers=headers)print(r.text)print(r.url)POST方法基本post請求在requests中,以form表單形式發(fā)送post請求,只需將請求的參數(shù)構造成一個字典,然后傳給data參數(shù)requests.post(url,data=None,json=None,**kwargs)importrequestsdata={"name":"yiqing","age":18}response=requests.post("/post",data=data)print(response.text)擬爬取的網(wǎng)站地址字典,字節(jié)序列或文件對象與params不同的是,data提交的數(shù)據(jù)并不接在url鏈接里,而是放在url對應位置的地方(例如form里)作為數(shù)據(jù)來存儲。JSON格式的數(shù)據(jù)向服務器傳送數(shù)據(jù)POST方法帶參數(shù)post請求在requests中,以form表單形式發(fā)送post請求,只需將請求的參數(shù)構造成一個字典,然后傳給data參數(shù)requests.post(url,data=None,json=None,**kwargs)importrequestsdata={"name":"Sharon","age":10}headers={"User-Agent":"Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/63.0.3239.84Safari/537.36"}response=requests.post("/post",data=data,headers=headers)print(response.text)文件上傳importrequestsfs={'file':open(‘logo.gif','rb')}resp=requests.post('/post',files=fs)print(resp.text)importrequestsurl='/post'fs={'file':open(‘G:/test.txt','rb')}r=requests.post(url,files=fs)print(r.text)建立Utf-8格式的txt文件:
test.txt并上傳上傳圖片文件logo.gif直接用files參數(shù)文件上傳:用open方式打開文件,與file形成鍵值對,定義成字典,并將其與files做關聯(lián),同時對應到相關url。以之向鏈接提交文件。網(wǎng)絡爬蟲按尺寸分類全internet網(wǎng)站網(wǎng)頁規(guī)模很小,獲取網(wǎng)絡的數(shù)據(jù)量也很小,對爬取速度要求不高。通常使用requests庫實現(xiàn)。針對特定或者一系列網(wǎng)頁能夠發(fā)揮很大的作用,最為常見。網(wǎng)站上內(nèi)容很多,對應的數(shù)據(jù)規(guī)模較大,爬取速度必須足夠趕上網(wǎng)站本身數(shù)據(jù)更新的速度。通常使用例如Scrapy之類更為專業(yè)的庫。如Google、百度,作用是建立全依賴的搜索引擎,規(guī)模很大。需要一個能夠爬取全internet所有資源的爬蟲,對爬取速度要求非常高,必須定制開發(fā)。網(wǎng)絡爬蟲引發(fā)的問題對服務器性能的騷擾內(nèi)容層面的法律風險個人隱私泄露服務器默認按照人數(shù)來約定訪問能力網(wǎng)絡爬蟲用計算機快速運算能力(十萬/s~幾十萬/s)去爬取網(wǎng)站內(nèi)容以獲取相關資源,對網(wǎng)站來說形成騷擾,為服務器帶來巨大資源開銷網(wǎng)站服務器上的數(shù)據(jù)往往有產(chǎn)權歸屬如果爬蟲爬取網(wǎng)站提供的數(shù)據(jù)以進行牟利,有可能會帶來法律上的風險網(wǎng)絡爬蟲具備一定的突破能力如果爬取網(wǎng)站上受保護的個人隱私數(shù)據(jù),將給個人帶來很大的隱私泄露風險。對網(wǎng)絡爬蟲的限制服務器或者網(wǎng)站的所有者可通過來源審查限制網(wǎng)絡爬蟲。判斷所有請求網(wǎng)絡鏈接HTTP頭部的user-agent字段,對于不是預定的瀏覽器可以限制其訪問。發(fā)布Robots協(xié)議,通知所有的爬蟲本網(wǎng)站可爬取的策略和規(guī)則。但是,Robots協(xié)議僅僅是通過發(fā)布來體現(xiàn),至于是否遵守仍是由網(wǎng)絡爬蟲自身決定。Robots協(xié)議
(RobotsExclusionProtocol
網(wǎng)絡爬蟲排除標準)作用:通知網(wǎng)絡爬蟲本網(wǎng)站可爬取的策略和規(guī)則,哪些頁面可以抓取,哪些不允許訪問網(wǎng)站時首先將檢查協(xié)議文件,以確定訪問的范圍User-agent
表明的是爬蟲來源,如果是*代表所有的爬蟲;Disallow
代表不允許這個爬蟲訪問的資源目錄或網(wǎng)址;Allow代表允許該爬蟲訪問的資源目錄或網(wǎng)址。User-agent:EtaoSpiderDisallow:/User-Agent:*Disallow:/pop/*.htmlDisallow:/?*針對EtaoSpider禁止訪問任何部分針對所有爬蟲禁止訪問pop目錄下所有html網(wǎng)址禁止訪問網(wǎng)站中所有包含問號開頭(?)的網(wǎng)址/robots.txt優(yōu)化異常處理?文件夾或路徑存在?文件沒有關閉?不能用原始文件名保存圖片?importrequestsimportosurl="/imgextra/i2/2895983329/O1CN011aSiyVIqb4ya7wU_!!2895983329.jpg"root="e://"path=root+url.split('/')[-1]try: ifnotos.path.exists(root): os.mkdir(root) ifnotos.path.exists(path): r=requests.get(url) withopen(path,'wb')asf: f.write(r.content) print("文件保存成功") else: print("文件已存在")except: print("爬取失敗")課后實驗爬取百度/必應首頁html代碼,顯示response對象的text內(nèi)容觀察response對象的狀態(tài)碼、編碼方式和httpheader修改header,并傳遞參數(shù)到url通過傳遞關鍵字”同濟大學”,爬取搜索的結(jié)果選取一張結(jié)果圖片,將其保存到本地對于用戶輸入的任意關鍵詞,獲取360搜索網(wǎng)站(/)任意搜索一個關鍵詞KeyWord,然后觀察其url地址。根據(jù)用戶輸入的關鍵詞,設置好當前url,使用requests庫的get()方法實現(xiàn)對指定url的請求,并觀察response響應對象的url鏈接和text內(nèi)容。拓展:政府工作報告-詞云繪制圖1.引入第三方庫2.爬取網(wǎng)頁文件3.詞云繪制#引入第三方庫importrequestsfrombs4importBeautifulSoupfromwordcloudimportWordCloud,STOPWORDSimportmatplotlib.pyplotaspltimportnumpyasnpimportPIL.ImageasImage#圖像處理#爬取網(wǎng)頁文件url="/premier/2022-03/12/content_5678750.htm"r=requests.get(url)r.encoding=r.apparent_encodingsoup=BeautifulSoup(r.text,"html.parser")content=soup.find("div",class_="pages_content").textprint(content)#詞云圖繪制mask=np.array(Image.open(r'五角星.png'))#通過generate(content)方法,將文本content生成一個WordCloud對象w=WordCloud(#設置字體格式font_path='C:/Windows/Fonts/simhei.ttf',background_color='white',#默認為黑色stopwords=STOPWORDS.add(“各位代表”),#過濾詞匯mask=mask,#設置遮罩圖片max_words=1000,#最多顯示詞數(shù)max_font_size=40)#字體最大值c=w.generate(content)c.to_file("pic1.png")#將詞云輸出為圖像文件plt.subplot(111)plt.imshow(c)#顯示詞云圖plt.axis('off')#不顯示坐標軸plt.show()#顯示圖像同濟大學計算機基礎教研室第五章網(wǎng)絡爬蟲與信息提取
5.2信息解析三大解析方法使用Requests獲取到網(wǎng)頁的HTML代碼信息后,怎樣分析得到我們想要的信息?BeautifulSoup是一個HTML或XML解析庫,用于格式化和組織復雜的網(wǎng)頁信息,是解析、遍歷、維護“標簽樹”的功能庫。方法效率難度BeautifulSoup慢最簡單正則表達式最快困難Xpath快正常引例:豆瓣電影名稱提取代碼importrequestsfrombs4importBeautifulSoupurl="/cinema/nowplaying/shanghai/"headers={'User-Agent':"Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/74.0.3729.108Safari/537.36"}r=requests.get(url,headers=headers)#獲取頁面信息soup=BeautifulSoup(r.text,'html.parser')#分析頁面#找到所有的電影信息對應的li標簽movie_list=soup.find_all('li',class_='list-item')#遍歷所有l(wèi)i標簽,分別獲取電影名稱foriteminmovie_list:print(item['data-title'])<pclass="title"></p>html源代碼由很多尖括號構成的標簽組織而成標簽樹標簽之間存在上下游關系文件BeautifulSoup庫BeautifulSoup是解析、遍歷、維護“標簽樹”的功能庫BeautifulSoup庫支持多種解析器,可方便地提取HTML或XML標簽中的內(nèi)容。BeautifulSoup提供一些簡單的、python式的函數(shù)用來處理導航、搜索、修改分析樹等功能。BeautifulSoup使用編碼自動檢測庫識別輸入文檔編碼并轉(zhuǎn)換為Unicode編碼,輸出文檔均轉(zhuǎn)換為utf-8編碼。BeautifulSoup可以對任何標簽類型的文件進行頁面內(nèi)容解析安裝和引用在Windows平臺以管理員身份運行cmd,運行下列語句進行庫的安裝:pipinstallbeautifulsoup4在AnacondaPrompt下安裝:condainstallbeautifulsoup4引用方式frombs4importBeautifulSoupimportbs4HTML網(wǎng)頁結(jié)構<html></html><head></head><title>頁面標題</title><body></body><h1>這是一個標題</h1><p>這是一個段落。</p>只有<body>區(qū)域才會在瀏覽器中顯示HTML元素以開始標簽起始、以結(jié)束標簽終止,元素內(nèi)容是開始標簽與結(jié)束標簽之間的內(nèi)容HTML文檔中的一個段落HTML文檔的主體整個HTML文檔嵌套的HTML元素超文本標記語言HyperText
Markup
Language使用標簽描述文檔結(jié)構和表現(xiàn)形式<標簽>內(nèi)容</標簽>htmlheadtitlebodyph1創(chuàng)建beautifulsoup對象在瀏覽器中,右擊“檢查”,比較幾種結(jié)果importrequestsfrombs4importBeautifulSoup#導入bs4庫r=requests.get('/')soup=BeautifulSoup(r.text,"html.parser")#html解析print(soup.prettify())#格式化輸出,增加換行符,分行顯示soup=BeautifulSoup(html,"html.parser")BeautifulSoup解析器BeautifulSoup可以解析多種格式的文檔soup=BeautifulSoup(r.text,“html.parser”)#response對象的text解析器使用方法使用前提特點bs4的html解析器html.parserpipinstallbeautifulsoup4執(zhí)行速度適中;文檔容錯力強lxml的html解析器lxmlpipinstalllxml速度快;文檔容錯能力強lxml的xml解析器xmlpipinstallxml速度快;唯一支持XML的解析器html5lib的解析器html5libpipinstallhtml5lib更好的容錯性;以瀏覽器的方式解析文檔soup=BeautifulSoup(‘<html>data</html>’,‘html.parser’)#html或xml文本soup=BeautifulSoup(open(‘a(chǎn).html’),“html.parser“)#網(wǎng)頁對象實例—上海當日天氣/weather/101020100.shtmlimportrequestsfrombs4importBeautifulSoupurl="/weather/101020100.shtml"r=requests.get(url)r.encoding=r.apparent_encodingsoup=BeautifulSoup(r.text,"html.parser")name=soup.find_all(class_="skyskyidlv3on")foruinname:day=u.h1.stringwea=u.find(class_="wea").texttem=u.find(class_="tem").get_text()win=u.find(attrs={"class":"win"}).get_text()content="日期:"+day+"天氣:"+wea+"溫度:"+tem+"風力:"+wincontent=content.replace("\n","")print(content)實例—上海當日天氣拓展上海7日天氣預報?引入正則任意城市7日天氣預報?根據(jù)城市編碼生成任意城市鏈接任意城市周邊地區(qū)當日天氣?多個周邊地區(qū)任意城市周邊地區(qū)7日天氣預報?根據(jù)每個周邊地區(qū)鏈接importrequestsfrombs4importBeautifulSoupurl="/weather/101020100.shtml"r=requests.get(url)r.encoding=r.apparent_encodingsoup=BeautifulSoup(r.text,"html.parser")name=soup.find_all(class_=pile("^skyskyidlv"))foruinname:day=u.h1.stringwea=u.find(class_="wea").text#text屬性
tem=u.find(class_="tem").get_text()#get_text方法
win=u.find(attrs={"class":"win"}).get_text()#設置attrscontent="日期:"+day+"天氣:"+wea+"溫度:"+tem+"風力:"+wincontent=content.replace("\n","")print(content)實例—上海7日天氣15日天氣預報?任意城市7日天氣預報搜索天氣網(wǎng)城市編碼保存到txt文檔,將“=>”替換成“:”手動拷貝賦值給字典citycName=input("城市名稱:")print("{}7日天氣預報".format(cName))code=city[cName]url="/weather/"+code+".shtml"#調(diào)用自定義函數(shù)get7DaysWeather(url)get7DaysWeather(url)defget7DaysWeather(url):r=requests.get(url)r.encoding=r.apparent_encodingsoup=BeautifulSoup(r.text,"html.parser")name=soup.find_all(class_=pile("^skyskyidlv"))foruinname:day=u.h1.stringwea=u.find(class_="wea").text#text屬性
tem=u.find(class_="tem").get_text()#get_text方法
win=u.find(attrs={"class":"win"}).get_text()#設置attrscontent="日期:"+day+"天氣:"+wea+"溫度:"+tem+"風力:"+wincontent=content.replace("\n","")print(content)任意城市周邊地區(qū)當日天氣函數(shù)getLink(cName),根據(jù)城市名稱得到城市鏈接defgetLink(cName):fp=open(r"城市編碼.txt","r")r="{"+fp.read()+"}"cityCode=eval(r)cityCode[cName]code=city[cName]url="/weather/"+code+".shtml"returnurl任意城市周邊地區(qū)當日天氣defgetRegionInfo(url):r=requests.get(url)r.encoding=r.apparent_encodingsoup=BeautifulSoup(r.text,"html.parser")info=soup.find('ul',class_="clearfixcity")info=info.find_all("li")regionInfo={}
#獲取每個周邊地區(qū)的名稱及其鏈接
foriinrange(len(info)):name=info[i].find('span').texttem=info[i].find('i').text#link=info[i].find('a').get('href').replace("#around2",'')regionInfo[name]=temreturnregionInfo主函數(shù)defmain():cName=input("城市名稱:")url=getLink(cName)regionInfo=getRegionInfo(url)forname,teminregionInfo.items():print("{}:氣溫{}".format(name,tem))main()任意城市周邊地區(qū)的7日天氣預報?案例文檔html="""<html><head><title>網(wǎng)絡爬蟲之學習</title></head><body><pclass="title"name="spider"><b>爬蟲之信息解析</b></p><pclass="method">下面介紹了兩種解析方法<ahref="/bs"class="method"id="link1">BeautifulSoup</a>,<ahref="/re"class="method"id="link2">正則表達式</a>,兩種方法各有特點</p><pclass="result">...</p></body></html>"""結(jié)構htmlheadtitlebodypbpaap<html><head><title>網(wǎng)絡爬蟲之學習</title></head><body><pclass="title"name="spider"><b>爬蟲之信息解析</b></p><pclass="method">下面介紹了兩種解析方法<ahref="/bs"class="method"id="link1">BeautifulSoup</a>,<ahref="/re"class="method"id="link2">正則表達式</a>,
兩種方法各有特點</p><pclass="result">...</p></body></html>BeautifulSoup類的基本元素基本元素說
明Tag標簽,最基本的信息組織單元。用<>和</>標明開頭和結(jié)尾Name標簽的名字,比如
<ahref="xxx">,a就是標簽名。格式:<tag>.nameAttributes標簽的屬性,字典形式組織,格式:<tag>.attrsNavigableString標簽內(nèi)非屬性字符串,<a></a>中間部分的字符串。格式:<tag>.stringComment標簽內(nèi)字符串的注釋部分,<!--...-->中的部分字符串。<ahref=""class="University">TongJi<!--Uni--></a>Tag:返回標簽內(nèi)容
創(chuàng)建beautifulsoup對象soup=BeautifulSoup(html)soup=BeautifulSoup(open('index.html'))print(soup.prettify())獲取標簽soup.titlesoup.headsoup.asoup.ptype(soup.a)直接用html文本將本地index.html文件打開,用之創(chuàng)建soup對象格式化輸出soup對象的內(nèi)容利用soup加標簽名輕松地獲取標簽的內(nèi)容注:它查找的是在所有內(nèi)容中的第一個符合要求的標簽驗證對象的類型:#<class'bs4.element.Tag'>soup.標簽名<html><head><title>網(wǎng)絡爬蟲之學習</title></head><body><pclass="title"name="spider"><b>爬蟲之信息解析</b></p><pclass="method">下面介紹了兩種解析方法<aclass="method"href="/bs"id="link1">BeautifulSoup</a>soup.title
soup.head
soup.p
soup.a
注:查找的是在所有內(nèi)容中的第一個符合要求的標簽type(soup.a)soup.p.nameName:標簽名字
(字符串類型)獲取標簽名字[document]headsoup對象本身比較特殊,它的name即為[document]內(nèi)部標簽,輸出的值即為標簽本身的名稱bodyp<tag>.nametagnameattrs<html><head><title>網(wǎng)絡爬蟲之學習</title></head><body><pclass="title"name="spider"><b>爬蟲之信息解析</b></p><pclass="method">下面介紹了兩種解析方法<aclass="method"href="/bs"id="link1">BeautifulSoup</a>
soup.name
[document]屬性(Attributes):說明標簽特點的區(qū)域獲取標簽屬性soup.p.attrssoup.p['class']soup.p.get('class')soup.p['class']="newClass"delsoup.p['class']{'class':['title'],'name':'spider'}p標簽的所有屬性;類型:字典['title']單獨獲取class屬性['title']利用get方法傳入屬性的名稱修改屬性刪除屬性<tag>.attrssoup.attrs空字典
tagnameattrs<html><head><title>網(wǎng)絡爬蟲之學習</title></head><body><pclass="title"name="spider"><b>爬蟲之信息解析</b></p><pclass="method">下面介紹了兩種解析方法<aclass="method"href="/bs"id="link1">BeautifulSoup</a>soup.p.attrs['class']soup.p['class']soup.p.attrssoup.p.get('class')p標簽的所有屬性單獨獲取class屬性利用get方法傳入屬性的名稱soup.p['class']="newC"修改屬性delsoup.p['class']刪除屬性"newC"{'class':['title'],'name':'spider'}內(nèi)容(NavigableString):
標簽內(nèi)部字符串獲取標簽的內(nèi)容soup.b.stringtype(soup.b.string)soup.a.stringsoup.p.stringsoup.html.string爬蟲之信息解析<class'bs4.element.NavigableString'>BeautifulSoup<tag>.string爬蟲之信息解析如果tag只有一個NavigableString類型子節(jié)點,那么這個tag可以使用.string得到子節(jié)點。如果一個tag僅有一個子節(jié)點,那么這個tag也可以使用.string方法,輸出結(jié)果與當前唯一子節(jié)點的.string結(jié)果相同。Nonetag包含了多個子節(jié)點,tag無法確定<html><head><title>網(wǎng)絡爬蟲之學習</title></head><body><pclass="title"name="spider"><b>爬蟲之信息解析</b></p><pclass="method">下面介紹了兩種解析方法<aclass="method"href="/bs"id="link1">BeautifulSoup</a>soup.p.stringsoup.a.stringsoup.b.stringsoup.html.stringNone如果一個tag僅有一個子節(jié)點,那么這個tag也可以使用.string方法,輸出結(jié)果與當前唯一子節(jié)點的.string結(jié)果相同。Comment:
標簽內(nèi)字符串的注釋部分獲取注釋<!—注釋-->soup.a.stringtype(soup.a.string)注釋是特殊的NavigableString對象iftype(soup.a.string)==bs4.element.Comment:print(soup.a.string)BeautifulSoup<class'bs4.element.Comment'>可利用.string來輸出它的內(nèi)容需通過類型區(qū)分兩者??梢栽谑褂们白鲆幌屡袛啾闅vhtmlheadtitlebodypbpaap下行遍歷上行遍歷平行遍歷<html><head><title>網(wǎng)絡爬蟲之學習</title></head><body><pclass="title"name="spider"><b>爬蟲之信息解析</b></p><pclass="method">下面介紹了兩種解析方法<ahref="/bs"class="method"id="link1">BeautifulSoup</a>,<ahref="/re"class="method"id="link2">正則表達式</a>,
兩種方法各有特點</p><pclass="result">...</p></body></html>基于bs4庫的html內(nèi)容遍歷遍歷屬性說明.contents子節(jié)點的的列表,將所有兒子節(jié)點存入列表.children子節(jié)點的迭代類型,與.contents類似,用于循環(huán)遍歷兒子節(jié)點.descendants子孫節(jié)點的迭代類型,包含所有子孫節(jié)點,用于循環(huán)遍歷.parent節(jié)點的父親標簽.parents節(jié)點的父輩標簽,包含父親,爺爺及以上.next_sibling返回按照html文本順序的下一個平行節(jié)點標簽.previous_sibling返回按照html文本順序的上一個平行節(jié)點標簽.next_siblings迭代類型,返回按照html文本順序的后續(xù)所有平行節(jié)點標簽.previous_siblings返回按照html文本順序的前序平行節(jié)點標簽.contents
.childrencontents屬性將tag的子節(jié)點以列表的方式輸出soup.head.contentssoup.body.contents輸出方式為列表,可以用列表索引來獲取它的某一個元素soup.body.contents[1]children返回的不是一個list,是一個
list生成器對象,可以通過遍歷獲取所有子節(jié)點soup.head.childrenlist(soup.body.children)forchildinsoup.body.children: print(child)[<title>網(wǎng)絡爬蟲之學習</title>]<list_iteratorat0xe713310>屬性直接子節(jié)點<html><head><title>網(wǎng)絡爬蟲之學習</title></head><body><pclass="title"name="spider"><b>爬蟲之信息解析</b></p><pclass="method">下面介紹了兩種解析方法<aclass="method"href="/bs"id="link1">BeautifulSoup</a>soup.head.contentssoup.body.contentssoup.head.contents[0]soup.head.childrensoup.body.contents[1].descendants屬性.descendants屬性可以對tag的所有子孫節(jié)點進行遞歸循環(huán)forchildinsoup.body.descendants: print()注意:而.contents
和
.children
屬性僅包含tag的直接子節(jié)點
所有子孫節(jié)點.strings
stripped_strings和string屬性相比,strings獲取多層內(nèi)容,可遍歷獲取forstringinsoup.strings: print(string)輸出的字符串中可能包含了很多空格或空行,使用stripped_strings可以去除多余空白內(nèi)容forstringinsoup.stripped_strings: print(string)屬性
.parent屬性父節(jié)點bodyheadtitle<html><head><title>網(wǎng)絡爬蟲之學習</title></head><body><pclass="title"name="spider"><b>爬蟲之信息解析</b></p><pclass="method">下面介紹了兩種解析方法<aclass="method"href="/bs"id="link1">BeautifulSoup</a>.parents屬性通過元素的.parents屬性可以遞歸得到元素的所有父輩節(jié)點forparentinsoup.a.parents: print()forparentinsoup.p.string.parents: print()全部父節(jié)點htmlheadtitlebodypbpaapsoup.a.parentssoup.p.string.parents.next_sibling
.previous_sibling.next_sibling屬性獲取節(jié)點的下一個兄弟節(jié)點(同一級節(jié)點),.previous_sibling則獲取上一個兄弟節(jié)點。注意:實際文檔中的tag.next_sibling和.previous_sibling
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 三農(nóng)信息人才培養(yǎng)計劃及實施方案
- 多領域融合的智能科技項目開發(fā)協(xié)議
- 工程項目居間的合同
- 化工廠員工勞動協(xié)議
- 經(jīng)營承包合同
- 勞務輸出合作協(xié)議書
- 第2課 獎品數(shù)量好計算(教學設計)2024-2025學年五年級上冊信息技術泰山版
- 新媒體主播合約協(xié)議書8篇
- Unit 8 Knowing the world Lesson 2 My home country 教學設計 2024-2025學年冀教版英語七年級上冊
- 甘肅幼兒園塑膠施工方案
- 消防工程施工施工方法及工藝要求
- 部編版道德與法治六年級下冊課程綱要
- DL-T439-2018火力發(fā)電廠高溫緊固件技術導則
- 人員測評方案
- 簡易呼吸器的使用和心肺復蘇-3
- 2024年河北省九地市中考數(shù)學摸底試卷
- (正式版)JBT 14787-2024 可同步限矩型液力耦合器
- 流行音樂(中國)
- 《標準字體設計》課件
- 2023年6月浙江高考政治試卷真題解讀及答案解析(課件)
- 銷售部廉政培訓課件
評論
0/150
提交評論