文章目錄
-
- 一、準備工作
- 1.安裝python3.7
- 2.安裝爬取豆瓣top250所需包
- 二、爬取網頁
- 1.分析網頁
- 2.爬取網頁
- 3.資訊篩選
- 4.複制整個網頁的xpath路徑
- 5.擷取第一頁每個電影的名字
- 6.擷取連結
- 7.評分
- 8.評價人數
- 9.排名
- 10.美化
- 11用正規表達式re比對星級數中的數字
- 12.寫入檔案夾
一、準備工作
1.安裝python3.7
打開浏覽器搜尋python,得到如下結果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN2XjlGcjAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL1kFVNlXS61EMRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZwpmLwczMwQTNxUTMyEDNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
打開圖檔中箭頭網址
或直接通路python官網打開得到以下畫面
下拉網頁
選擇自己需要的版本
點選後面的download即可下載下傳。
具體安裝可以參考其他博友文章,這裡不進行過多贅述。
2.安裝爬取豆瓣top250所需包
所需要的包有,jupyter(個人習慣的編輯環境,可以不安裝)、re(正規表達式)、request、lxml、csv
安裝所需包的過程:電腦鍵盤按住win+R,打開控制台,輸入cmd,點選确定或回車啊。
安裝包的公式為pip install ******
以安裝第一個包為例,輸入pip install jupyter,回車,就可以線上安裝了
初次安裝會需要一些時間,耐心等待一會,其他的包同理。
二、爬取網頁
1.分析網頁
在此處我們爬取豆瓣電影top250的電影資訊
打開可以看到網頁如下
我們可以看到本頁隻有25部電影,我們的任務是爬取250部電影,共十頁,分析每一頁的差別,此處打開前三頁和最後一頁的網址對比
第一頁
https://movie.douban.com/top250?start=0&filter=
第二頁
https://movie.douban.com/top250?start=25&filter=
第三頁
https://movie.douban.com/top250?start=50&filter=
最後一頁(第十頁)
https://movie.douban.com/top250?start=225&filter=
由分析我們可以知道,每一頁的網址是差不多的,唯一的差别就是數字的變動,每一頁的數值變化為25,
![]()
使用python3.7爬取豆瓣電影top250資訊
除此之外,其餘部分都是一樣的。我們可以用一個for循環數組代碼來實作這個網頁
運用range函數,可以得到十個間隔為25的數組
此處的是226,而不是225是因為range函數後面的括号為前閉後開區間,即為前可取後不可取,三個數字代表的含義分别為從0開始,到226結束,間隔25.
将start=0改為start=%s,後面跟的%page表示将page函數中的數 值範圍賦予給s,即可一次性構造出十個網頁的連結,代碼如下:
for page in range(0, 226, 25):
url = 'https://movie.douban.com/top250?start=%s&filter='%page
print (url)
運作代碼可以得到如下圖結果:
至此,我們已經得到了十個網頁的代碼了。
2.爬取網頁
打開豆瓣網頁,對網頁進行審查,
右擊進入檢查元素,點選網絡(network),再點選所有(All)
對該網頁進行重新整理,下方會出現網頁的組成元素,例如圖檔等
用箭頭标出來的分别為請求方法和狀态碼,即我們使用的方法為get,傳回的狀态碼為200則為成功,傳回其他數值則不成功。
使用get語句通路浏覽器,得到如下結果,意義為:系統識别出為非正常通路,拒絕傳回值
此處我們需要僞裝浏覽器,用以躲過網站的識别,首先,講代碼審查中的使用者代理複制過來,構造字典,使用者代理的位置為:
豆瓣top250中右鍵檢查,notework,all,下拉導航,出現的
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36
即為使用者代理。
import requests
test_url = 'https://movie.douban.com/top250?start=0&filter='
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}
requests.get(url=test_url,headers=headers)
運作即可得到狀态碼為200的傳回值
在代碼後加入.text,即可得到以下内容。
我們可以看到,我們雖然成功得爬取了網頁資料,不過看上去是很雜亂的,我們還需要篩選資料。
我們加上一句代碼
reponse=requests.get(url=test_url,headers=headers).text
#中間一行空格
reponse
3.資訊篩選
工具:xpath,re,BeautifulSoup,工具需要提前安裝,安裝教程檢視本文開頭目錄,這裡不做過多贅述。
假如我要從網頁資訊中篩選出“這個殺手不太冷”的電影的名字
#從lxml包裡面到處etree這個工具
from lxml import etree
#使用etree解析網頁
html_etree = etree.HTML (reponse)
#定位
html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li[4]/div/div[2]/div[1]/a/span[1]/text()')
得到如下結果
網頁檢查中的定位怎麼查找:打開網頁,找到你想查找的資料,點選檢查,在出現的代碼中找到你所選擇的内容,右鍵copy xpath。在xpath後面添加/ text()字尾即可查找。
4.複制整個網頁的xpath路徑
打開網頁,右擊檢查元素,找到每個電影子產品對應的序列代碼,如下圖
将圖中右側滑鼠選中的位置的xpath路徑複制下來為:
第一個://[@id=“content”]/div/div[1]/ol/li[1]
第二個://[@id=“content”]/div/div[1]/ol/li[2]
第三個://*[@id=“content”]/div/div[1]/ol/li[3]
我們可以分析,每一部電影的結構都大緻相似,隻有最後的數字不一樣。
将上面的代碼表示出來為
html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li[1]')
html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li[2]')
html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li[3]')
将最後的[數字]删除,即可表示所有的xpath路徑。即
html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li')
可以表示所有的路徑。
輸入len(li)即可檢視路徑長度
5.擷取第一頁每個電影的名字
item可以自己命名,name為電影名字,可自己命名
整個語句可了解為,從25個xpath路徑裡面擷取得250個電影,然後再從這250個電影(item)的xpath路徑裡面擷取250個電影名(name)
第一個://[@id=“content”]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1]
第二個://[@id=“content”]/div/div[1]/ol/li[2]/div/div[2]/div[1]/a/span[1]
可看出,兩個連結隻有/li[]中的數字不一樣,
from lxml import etree html_etree = etree.HTML (reponse) li=html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li') for item in li: name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()') print(name)
得到如下結果:
後面加上[0],可以得到
6.擷取連結
對電影的連結進行分析
第一個://[@id=“content”]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a
第二個://[@id=“content”]/div/div[1]/ol/li[2]/div/div[2]/div[1]/a
隻有li[]不一樣,其他的都是一樣的,做法同上一個擷取電影名稱
代碼如下:
from lxml import etree
html_etree = etree.HTML (reponse)
li=html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
for item in li:
name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()')
print(name)
dy_url = item.xpath('./div/div[2]/div[1]/a/@href')
print(dy_url)
運作:
7.評分
第一個://[@id=“content”]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[1]
第二個://[@id=“content”]/div/div[1]/ol/li[2]/div/div[2]/div[2]/div/span[1]
同理,代碼不一樣
from lxml import etree
html_etree = etree.HTML (reponse)
li=html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
for item in li:
name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()')
print(name)
dy_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
print (dy_url)
rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
print(rating)
8.評價人數
第一個://[@id=“content”]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[4]
第二個://[@id=“content”]/div/div[1]/ol/li[2]/div/div[2]/div[2]/div/span[4]
同理:
from lxml import etree
html_etree = etree.HTML (reponse)
li=html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
for item in li:
name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()')
print(name)
dy_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
print (dy_url)
rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
print(rating)
content=item.xpath('./div/div[2]/div[2]/div/span[4]/text()')
print(content)
9.排名
原理同上
10.美化
輸入’~’*50, 可以加波浪線,50為個數
11用正規表達式re比對星級數中的數字
如爬取到的星級數為rating5-t或rating4.5-t,但我們隻想要數字,故用正規表達式來比對
re正規表達式文法較複雜,平時可在網上多學習
準備工作:引入re包,import re
我們首先要知道一些關于正規表達式的使用方法,正規表達式替換的方法是.*?替換。
例如:
import re
a = "123人評價"
re.findall('(.*?)人評價', a)
則輸出為123.
這樣輸出的rating分數,還是有一點問題,那就是本來應該是4.5的變為了45,是以我們還需要設定一個條件語句,
if len(rating) == 2:
star = int(rating) / 10 #int()轉化為數字
else:
star = rating
意義為當rating長度為2的時候,除以十,當rating長度不為2,就不改變。
12.寫入檔案夾
分為三個步驟,1.建立檔案夾并打開
fp = open("./豆瓣top250.csv", 'a', newline='', encoding = 'utf-8-sig') writer = csv.writer(fp)
2.寫入
writer.writerow(('排名', '名稱', '連結', '星級', '評分', '評價人數'))
writer.writerow((rank, name, dy_url, star, rating_num, content))
3.關閉
插入代碼中,運作即可
在此處我們看不到檔案,傳回jupyter檔案夾,打開即可看到檔案
打開可以看到
至此,我們本次任務完成。
代碼彙總:
import requests, csv, re
from lxml import etree
#設定浏覽器代理,它是一個字典
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}
# 建立檔案夾并打開
fp = open("./豆瓣top250.csv", 'a', newline='', encoding = 'utf-8-sig')
writer = csv.writer(fp) #我要寫入
# 寫入内容
writer.writerow(('排名', '名稱', '連結', '星級', '評分', '評價人數'))
for page in range(0, 226, 25): #226
print ("正在擷取第%s頁"%page)
url = 'https://movie.douban.com/top250?start=%s&filter='%page
#請求源代碼,向伺服器送出請求,200代表成功,回退對其,Ctrl+]
reponse = requests.get(url = url, headers = headers).text
# 快捷鍵運作,Ctrl+Enter
html_etree = etree.HTML(reponse) # 看成一個篩子,樹狀
# 過濾
li = html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
for item in li:
#排名
rank = item.xpath('./div/div[1]/em/text()')[0]
#電影名稱
name = item.xpath('./div/div[2]/div[1]/a/span[1]/text()')[0]
#連結
dy_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
# print (dy_url)
#評分
rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
rating = re.findall('rating(.*?)-t', rating)[0]
if len(rating) == 2:
star = int(rating) / 10 #int()轉化為數字
else:
star = rating
# 注釋ctrl+?
rating_num = item.xpath('./div/div[2]/div[2]/div/span[2]/text()')[0]
content = item.xpath('./div/div[2]/div[2]/div/span[4]/text()')[0]
content = re.sub(r'\D', "", content)
# print (rank, name, dy_url, star, rating_num, content)
# 寫入内容
writer.writerow((rank, name, dy_url, star, rating_num, content))
fp.close()
通過本次作業,想說的是,自己不夠認真,很多處小錯誤,然後查找錯誤花費了很多時間,一些問題自己無法解決,參考了同學的作業,總的來說需要多從實戰之中擷取經驗。這次辛苦楊友同學老師了。