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

歡迎訪問 生活随笔!

生活随笔

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

python

[转载] Python新手写出漂亮的爬虫代码1——从html获取信息

發(fā)布時間:2025/3/11 python 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转载] Python新手写出漂亮的爬虫代码1——从html获取信息 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

參考鏈接: Python中從用戶獲取多個輸入

Python新手寫出漂亮的爬蟲代碼1?

初到大數(shù)據(jù)學(xué)習(xí)圈子的同學(xué)可能對爬蟲都有所耳聞,會覺得是一個高大上的東西,仿佛九陽神功和乾坤大挪移一樣,和別人說“老子會爬蟲”,就感覺特別有逼格,但是又不知從何入手,這里,博主給大家糾正一個誤區(qū):爬蟲并不神秘,也不高級,是一個非常好上手和掌握的東西(當(dāng)然,里面也有很多坑,也有很多細(xì)節(jié),展開說的話其實(shí)也蠻復(fù)雜的,不過它的模式和套路就擺在那里,看了小編的博客,保證你能爬下你想要的內(nèi)容)。?

一般情況下,爬蟲分為兩種,一種是靜態(tài)爬蟲,一種是動態(tài)爬蟲,所謂靜態(tài)爬蟲,就是大部分信息(至少你所需要的那些信息)是寫在html代碼中的,而動態(tài)爬蟲一般都是寫在一個json文檔中,這么說可能不太標(biāo)準(zhǔn),不過初學(xué)者這樣理解即可,這篇博客將會帶大家領(lǐng)略靜態(tài)爬蟲,下一篇將會講解動態(tài)爬蟲。?

補(bǔ)充一句,博主曾是忠實(shí)的Python2用戶,不過現(xiàn)在也改到Python3了,曾經(jīng)新的庫會在Python2中首先兼容,然后要過好久才在Python3中集成,現(xiàn)在完全不用擔(dān)心,Python2有了,Python3不日就會集成,Python3也會在編碼方面提供更多遍歷,推薦新手直接從Python3入手,當(dāng)然,二者沒有什么太大區(qū)別,遇到問題問問度娘就可以了了,廢話不多說,我們開始爬蟲的第一課!?

本篇博文將從以下幾個方面進(jìn)行講解? - 啥是Html代碼?? - 怎么從Html代碼中定位到我要的東西?? - BeautifulSoup神器? - 案例:愛卡汽車?

?

啥是Html代碼?

所謂的html代碼,瀏覽博客的你右手一定在鼠標(biāo)上,好的,跟著我左手右手一個慢動作,點(diǎn)擊右鍵,找到“查看網(wǎng)頁源代碼”,不同瀏覽器可能這個描述不太一樣,博主是Chrome,不過都差不太多,是不是有看到類似下面這個圖的一堆不知道是什么鬼的代碼??

?

其實(shí),你可以按鍵盤上的F12或者右鍵選擇“檢查元素”(不同瀏覽器不同),這時,瀏覽器的右側(cè)(如果你是360瀏覽器,可能是在下方)彈出一個東東,類似下面紅色框中的區(qū)域? ?

這個東西就是剛才我們看的那個不知道是什么鬼的東西的樹狀結(jié)構(gòu),看上去會整齊一些。這就是html代碼,html代碼其實(shí)就是用許多個"<Y yy='aaa'>xxxx</Y>"是的結(jié)構(gòu)將想要輸出在頁面上的內(nèi)容包含起來的一種語言。下一個小節(jié)將詳細(xì)介紹這個結(jié)構(gòu),總而言之,我們?nèi)庋鬯吹降臇|西大部分都來自于html代碼,html代碼的作用簡單來說就是程序員用一堆html代碼,將需要展示的信息放在指定的位置上的一種東西,有了html代碼,才有了你眼前頁面上的很多元素;當(dāng)然,還有其他方式來將元素展示在頁面上,如css、js等渲染方式,這些我們下一篇會介紹。?

知道我們所需要的信息位于html中,那么只需要找到我們需要的具體內(nèi)容在哪里,然后下載下來,就大功告成了,邏輯就是這么個邏輯,所以靜態(tài)爬蟲的關(guān)鍵問題是要準(zhǔn)確的解析html代碼,一般使用BeautifulSoup這個庫或者正則表達(dá)式。?

怎么從Html代碼中定位到我要的東西?

標(biāo)簽?

上一節(jié)中提到,html代碼中都是"<Y yy='aaa'>xxxx</Y>"結(jié)構(gòu),一對”<>”我們稱之為標(biāo)簽,這對標(biāo)簽中通常會有一些內(nèi)容,可能是一個數(shù)字,一段字符串,一個網(wǎng)頁鏈接,或者一個圖片鏈接等等,總之,就是我們在網(wǎng)頁上看到的內(nèi)容。”Y”稱之為標(biāo)簽名,”yy”為其屬性名,”aaa”是其屬性值,”xxxx”是這個標(biāo)簽的內(nèi)容,也就是對應(yīng)于頁面上的信息。一般情況下我們要獲取的就是”xxxx”,有時我們可能也需要獲取標(biāo)簽的屬性值”aaa”。標(biāo)簽可能是唯一的,也可能是有重復(fù)的,回看剛才那張樹狀的標(biāo)簽結(jié)構(gòu),有一種分明的層次感,同一層的標(biāo)簽我們稱他們互為兄弟標(biāo)簽,而一個標(biāo)簽和包含他的標(biāo)簽互為父子標(biāo)簽,如果a包含b,b包含c,d,則c是a的后代標(biāo)簽,是b的子標(biāo)簽,是d的兄弟標(biāo)簽,這個名字無所謂的,了解一下就好,一般標(biāo)簽名可能會重復(fù),但標(biāo)簽屬性名(yy)和屬性值“aaa”很少重復(fù),不過兄弟標(biāo)簽之間可能會出現(xiàn)標(biāo)簽名、屬性名、屬性值完全相同的情況,后面會介紹(就是find方法和findAll方法的區(qū)別)。?

好,上實(shí)例,打開一個網(wǎng)址把:http://newcar.xcar.com.cn/257/review/0.htm,是愛卡汽車中比亞迪F3的口碑頁面,鼠標(biāo)右鍵選擇“檢查元素”或者之間按鍵盤上的F12,選擇那個鼠標(biāo)的按鈕(紅色框1),然后將鼠標(biāo)放到評論框附近(紅色框2),如下圖所示,看到檢查元素界面中有一段代碼背景色變成了深色(如紅色框3)?

?

每個頁面有10條口碑,可見這10條口碑均存儲在屬性名為’class’,屬性值為’review_comments_dl’的’div’標(biāo)簽中,當(dāng)然,這個標(biāo)簽不是一個“葉節(jié)點(diǎn)”,也就是說這個標(biāo)簽內(nèi)部還有其他標(biāo)簽,我們進(jìn)一步看看。看下面的圖片。?

?

我們可以看到紅框3中有很多相同的標(biāo)簽<dl>...</dl>,他們都是屬性名為’class’,屬性值為’review_comments_dl’的’div’標(biāo)簽的子標(biāo)簽,他們之間互為兄弟標(biāo)簽,我們把鼠標(biāo)放在紅框3的位置并選中,這時左側(cè)網(wǎng)頁的第一條口碑的位置就會變成深色背景,也就是說,紅框3這個標(biāo)簽實(shí)際上對應(yīng)著紅框2這個區(qū)域中的內(nèi)容,那么我們把紅框3再具體的看一看。如下圖所示。?

?

可以看到,第一條口碑(紅框中的內(nèi)容)在第一個’dl’標(biāo)簽中(紅色下劃線2),同理可以看到第二條口碑在第二個’dl’標(biāo)簽中。再來看看這個’dl’標(biāo)簽,他有兩個子標(biāo)簽,’dt’和’dd’子標(biāo)簽,口碑?dāng)?shù)據(jù)位于dd子標(biāo)簽下;好的,再來看’dd’標(biāo)簽,將’dd’標(biāo)簽展開,如下圖所示。?

?

紅框3是該車的第一頁的第一條口碑,位于dd標(biāo)簽中,及圖中藍(lán)色下劃線<dd>...</dd> 中的內(nèi)容,圖中從開頭的dd指向紅框3,標(biāo)注了“同級”,意思是紅框3的內(nèi)容是dd標(biāo)簽的內(nèi)容,而dd標(biāo)簽下還有子標(biāo)簽,比如屬性為class,屬性值為useful的div標(biāo)簽,里面的內(nèi)容1034是有多少人覺得這個口碑有用;還有一個子標(biāo)簽p,p標(biāo)簽的內(nèi)容是口碑的作者;p中有一個子標(biāo)簽a,a標(biāo)簽的內(nèi)容是評論來源,如圖中的“比亞迪F3論壇”。?

好了,現(xiàn)在想必讀者已經(jīng)對通過標(biāo)簽定位信息有所了解了,我們再來練習(xí)一下,我們將口碑頁切換到第2頁,可以看到地址變成了http://newcar.xcar.com.cn/257/review/0/0_2.htm,多了一個’0_2’。將’0_2’改成’0_1’就跳回了第一頁(實(shí)際上第一頁的真實(shí)url是http://newcar.xcar.com.cn/257/review/0/0_1.htm),而改成’0_3’就到了第三頁。那么我們應(yīng)該怎么獲取該車型的口碑一共有幾頁呢?看下面的圖。?

?

依然是在開發(fā)者工具視角(及按F12彈出的窗口這個視角),將鼠標(biāo)放在尾頁(這里是122)或者‘下一頁’上,右側(cè)的框中會出現(xiàn)如圖所示的畫面,可以看到尾頁122所在的位于屬性為class,屬性值為’pagers’的div標(biāo)簽的倒數(shù)第二個子標(biāo)簽中,如紅框1所示;而’下一頁’則位于屬性為class,屬性值為’pagers’的div標(biāo)簽的最后一個子標(biāo)簽中,如紅框2所示。在仔細(xì)貫徹一下會發(fā)現(xiàn)屬性為class,屬性值為’pagers’的div標(biāo)簽與我們之前尋找口碑的標(biāo)簽dl是兄弟標(biāo)簽,位于全部的dl標(biāo)簽的再后面一個,也就是說,該標(biāo)簽的父標(biāo)簽與dl標(biāo)簽相同,即屬性名為’class’,屬性值為’review_comments_dl’的’div’標(biāo)簽。?

為什么要確定尾頁呢?因?yàn)闃?gòu)造代碼時,我們要知道代碼的起止位置,使用for循環(huán)良好的控制代碼的開始與完結(jié)。?

這個爬蟲的邏輯是這樣的:找到目標(biāo)的車型,即其url,實(shí)際上,不同車型的url只有id不同,比如比亞迪F3的url是http://newcar.xcar.com.cn/257/,其車子id是257,當(dāng)id更改為258時,車型就變成了比亞迪F0;然后查看html代碼,明確要爬取的內(nèi)容的所在位置,明確換頁規(guī)律,明確爬蟲的起止位置(獲取尾頁信息的html位置),然后構(gòu)造代碼。?

BeautifulSoup神器?

Python一個第三方庫bs4中有一個BeautifulSoup庫,是用于解析html代碼的,換句話說就是可以幫助你更方便的通過標(biāo)簽定位你需要的信息。這里只介紹兩個比較關(guān)鍵的方法:?

1、find方法和findAll方法:? 首先,BeautifulSoup會先將整個html或者你所指定的html代碼編程一個BeautifulSoup對象的實(shí)例(不懂對象和實(shí)例不要緊,你只要把它當(dāng)作是一套你使用F12看到的樹形html代碼代碼就好),這個實(shí)例可以使用很多方法,最常用的就是find和findAll,二者的功能是相同的,通過find( )的參數(shù),即find( )括號中指定的標(biāo)簽名,屬性名,屬性值去搜索對應(yīng)的標(biāo)簽,并獲取它,不過find只獲取搜索到的第一個標(biāo)簽,而findAll將會獲取搜索到的所有符合條件的標(biāo)簽,放入一個迭代器(實(shí)際上是將所有符合條件的標(biāo)簽放入一個list),findAll常用于兄弟標(biāo)簽的定位,如剛才定位口碑信息,口碑都在dl標(biāo)簽下,而同一頁的10條口碑對應(yīng)于10個dl標(biāo)簽,這時候用find方法只能獲取第一個,而findAll會獲取全部的10個標(biāo)簽,存入一個列表,想要獲取每個標(biāo)簽的內(nèi)容,只需對這個列表使用一個for循環(huán)遍歷一遍即可。?

2、get_text()方法:? 使用find獲取的內(nèi)容不僅僅是我們需要的內(nèi)容,而且包括標(biāo)簽名、屬性名、屬性值等,比如使用find方法獲取"<Y yy='aaa'>xxxx</Y>" 的內(nèi)容xxxx,使用find后,我們會得到整個"<Y yy='aaa'>xxxx</Y>",十分冗長,實(shí)際我們想要的僅僅是這個標(biāo)簽的內(nèi)容xxxx,因此,對使用find方法后的對象再使用get_text( )方法,就可以得到標(biāo)簽的內(nèi)容了,對應(yīng)到這里,我們通過get_text( )方法就可以得到xxxx了。?

好了,鋪墊做的差不多了,上代碼咯~~~?

案例:愛卡汽車?

使用Python3,需要提前安裝bs4庫,博主的環(huán)境是win7+Python3+Pycharm(有時候也用Ubuntu16.04+Python3+Pycharm),很多時候都有人問博主,什么ide好用呢?jupyter notebook?spyder?Pycharm?這里只能和大家說各個ide各有千秋,做工程(如爬蟲)使用pycharm肯定是首選,如果只是平時的練習(xí),寫個小程序,使用jupyter notebook和spyder就不錯,總之,如果涉及到頻繁打印輸出結(jié)果的東西,最好還是用pycharm,不要用jupyter notebook,不然會很卡。?

言歸正傳,上代碼!?

兩點(diǎn)說明:爬蟲代碼中,html代碼經(jīng)常會出現(xiàn)’class’這個屬性名,而class是python中“類”的關(guān)鍵字,而爬蟲的find方法對于屬性名而言,是不需要加引號的,如果直接輸入class是會出現(xiàn)問題的,所以需要注意,每次輸入class時應(yīng)當(dāng)輸入為class_,即class后加一個下劃線;?

第二就是下方代碼一開始有一個add_header的過程,為的是將代碼偽裝成瀏覽器。很多網(wǎng)站是反對爬蟲程序?qū)ζ湫畔⑦M(jìn)行爬取的,所以會禁止一些程序訪問他們的網(wǎng)站,通過add_header將你的爬蟲程序偽裝成了瀏覽器,故在網(wǎng)站看來,訪問它的就不是一個程序,而是一個瀏覽器,或者說是一個人類用戶了。?

import urllib

import urllib.request

from bs4 import BeautifulSoup

import re

import random

import time

?

# 設(shè)置目標(biāo)url,使用urllib.request.Request創(chuàng)建請求

url0 = "http://newcar.xcar.com.cn/257/review/0.htm"

req0 = urllib.request.Request(url0)

?

# 使用add_header設(shè)置請求頭,將代碼偽裝成瀏覽器

req0.add_header("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")

?

# 使用urllib.request.urlopen打開頁面,使用read方法保存html代碼

html0 = urllib.request.urlopen(req0).read()

?

# 使用BeautifulSoup創(chuàng)建html代碼的BeautifulSoup實(shí)例,存為soup0

soup0 = BeautifulSoup(html0)

?

# 獲取尾頁(對照前一小節(jié)獲取尾頁的內(nèi)容看你就明白了)

total_page = int(soup0.find("div",class_= "pagers").findAll("a")[-2].get_text())

myfile = open("aika_qc_gn_1_1_1.txt","a")

print("user","來源","認(rèn)為有用人數(shù)","類型","評論時間","comment",sep="|",file=myfile)

for i in list(range(1,total_page+1)):

? ? # 設(shè)置隨機(jī)暫停時間

? ? stop = random.uniform(1, 3)

? ? url = "http://newcar.xcar.com.cn/257/review/0/0_" + str(i) + ".htm"

? ? req = urllib.request.Request(url)

? ? req.add_header("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")

? ? html = urllib.request.urlopen(req).read()

? ? soup = BeautifulSoup(html)

? ? contents = soup.find('div', class_="review_comments").findAll("dl")

? ? l = len(contents)

? ? for content in contents:

? ? ? ? tiaoshu = contents.index(content)

? ? ? ? try:

? ? ? ? ? ? ss = "正在爬取第%d頁的第%d的評論,網(wǎng)址為%s" % (i, tiaoshu + 1, url)

? ? ? ? ? ? print(ss)

? ? ? ? ? ? try:

? ? ? ? ? ? ? ? comment_jiaodu = content.find("dt").find("em").find("a").get_text().strip().replace("\n","").replace("\t","").replace("\r","")

? ? ? ? ? ? except:

? ? ? ? ? ? ? ? comment_jiaodu = ""

? ? ? ? ? ? try:

? ? ? ? ? ? ? ? comment_type0 = content.find("dt").get_text().strip().replace("\n","").replace("\t","").replace("\r","")

? ? ? ? ? ? ? ? comment_type1 = comment_type0.split("【")[1]

? ? ? ? ? ? ? ? comment_type = comment_type1.split("】")[0]

? ? ? ? ? ? except:

? ? ? ? ? ? ? ? comment_type = "好評"

? ? ? ? ? ? # 認(rèn)為該條評價有用的人數(shù)

? ? ? ? ? ? try:

? ? ? ? ? ? ? ? useful = int(content.find("dd").find("div",class_ = "useful").find("i").find("span").get_text().strip().replace("\n","").replace("\t","").replace("\r",""))

? ? ? ? ? ? except:

? ? ? ? ? ? ? ? useful = ""

? ? ? ? ? ? # 評論來源

? ? ? ? ? ? try:

? ? ? ? ? ? ? ? comment_region = content.find("dd").find("p").find("a").get_text().strip().replace("\n","").replace("\t","").replace("\r","")

? ? ? ? ? ? except:

? ? ? ? ? ? ? ? comment_region = ""

? ? ? ? ? ? # 評論者名稱

? ? ? ? ? ? try:

? ? ? ? ? ? ? ? user = content.find("dd").find("p").get_text().strip().replace("\n","").replace("\t","").replace("\r","").split(":")[-1]

? ? ? ? ? ? except:

? ? ? ? ? ? ? ? user = ""

? ? ? ? ? ? # 評論內(nèi)容

? ? ? ? ? ? try:

? ? ? ? ? ? ? ? comment_url = content.find('dt').findAll('a')[-1]['href']

? ? ? ? ? ? ? ? urlc = comment_url

? ? ? ? ? ? ? ? reqc = urllib.request.Request(urlc)

? ? ? ? ? ? ? ? reqc.add_header("User-Agent",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")

? ? ? ? ? ? ? ? htmlc = urllib.request.urlopen(reqc).read()

? ? ? ? ? ? ? ? soupc = BeautifulSoup(htmlc)

? ? ? ? ? ? ? ? comment0 = \

? ? ? ? ? ? ? ? soupc.find('div', id='mainNew').find('div', class_='maintable').findAll('form')[1].find('table',class_='t_msg').findAll('tr')[1]

? ? ? ? ? ? ? ? try:

? ? ? ? ? ? ? ? ? ? comment = comment0.find('font').get_text().strip().replace("\n", "").replace("\t", "")

? ? ? ? ? ? ? ? except:

? ? ? ? ? ? ? ? ? ? comment = ""

? ? ? ? ? ? ? ? try:

? ? ? ? ? ? ? ? ? ? comment_time = soupc.find('div', id='mainNew').find('div', class_='maintable').findAll('form')[1].find('table', class_='t_msg').\

? ? ? ? ? ? ? ? ? ? find('div', style='padding-top: 4px;float:left').get_text().strip().replace("\n","").replace( "\t", "")[4:]

? ? ? ? ? ? ? ? except:

? ? ? ? ? ? ? ? ? ? comment_time = ""

? ? ? ? ? ? except:

? ? ? ? ? ? ? ? try:

? ? ? ? ? ? ? ? ? ? comment = content.find("dd").get_text().split("\n")[-1].split('\r')[-1].strip().replace("\n", "").replace("\t","").replace("\r", "").split(":")[-1]

? ? ? ? ? ? ? ? except:

? ? ? ? ? ? ? ? ? ? comment = ""

? ? ? ? ? ? # time.sleep(stop)

? ? ? ? ? ? print(user,comment_region,useful,comment_type,comment_time,comment, sep="|", file=myfile)

? ? ? ? except:

? ? ? ? ? ? s = "爬取第%d頁的第%d的評論失敗,網(wǎng)址為%s" % (i, tiaoshu + 1, url)

? ? ? ? ? ? print(s)

? ? ? ? ? ? pass

myfile.close()?

補(bǔ)充說明一下:try——except這個結(jié)構(gòu)(看起來有點(diǎn)像if——else的結(jié)構(gòu))是一個非常重要的過程,為了使爬蟲代碼可以良好的運(yùn)行,不至于剛開始爬幾分鐘就報錯這種惡心人的情況,需要很好的利用try——except過程。程序會先執(zhí)行try下的語句,如果發(fā)生失敗,就會執(zhí)行except下的語句,你也可以使用多個try——except嵌套的結(jié)構(gòu)完成復(fù)雜的情況的覆蓋,最好要保證你的try——except過程包含了程序會遇到的所有情況,那么你的代碼就是趨于完美的。?

講到這里,第一節(jié)爬蟲課程也就到這里了,不久之后會介紹動態(tài)爬蟲,如果之后還有時間,還會介紹一下selenium這個模擬瀏覽的庫,以及爬蟲框架還有反爬蟲的知識,給自己打個廣告,除了爬蟲可,近期也會分享一些關(guān)于word2vec和fastText文本分類算法的內(nèi)容,讀者有什么其他想交流的可以留言~我也是個正在學(xué)習(xí)路上的仔,希望能和各路朋友以及大牛交流。?

目錄?

?

?

??

? Python新手寫出漂亮的爬蟲代碼1

? ? 啥是Html代碼怎么從Html代碼中定位到我要的東西

? ? ? 標(biāo)簽 BeautifulSoup神器案例愛卡汽車

? ? ? 目錄

總結(jié)

以上是生活随笔為你收集整理的[转载] Python新手写出漂亮的爬虫代码1——从html获取信息的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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