一. 準備工作
網頁分析
首先對豆瓣電影的網頁URL進行分析:
豆瓣電影TOP250的首頁是
https://movie.douban.com/top250
而翻一頁之後變成了
https://movie.douban.com/top250?start=25&filter=
不難發現此時最上面的電影顯示的是第26名的電影,是以隻需要修改網頁連結中的25為指定數值,就可以模拟翻頁功能
每頁的URL不同之處:最後的數值 = (頁數-1)* 25
編碼規範
一般Python程式第一行加入
#coding=utf-8
保證代碼中的中文被正确解釋
Python檔案中可以加入main函數用于測試程式
預備知識
向伺服器請求
html
資料:
urllib
庫或者
request
庫
解析
html
内容:
BeautifulSoup
和
re
庫
輸出到excel:
xlwt
庫
二. 擷取資料
擷取指定URL對應的HTML資料——askURL函數
def askURL(url):
# 使用者代理,讓伺服器知道我們是什麼類型的機器和浏覽器
# 告訴伺服器我們可以接受什麼類型的資訊
head = { # 模拟浏覽器頭部資訊
"User-Agent":
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 "
"Safari/537.36 "
}
request = urllib.request.Request(url, headers=head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
# print(html)
except urllib.error.URLError as e:
if hasattr(e, "code"): # 如果有code标簽,輸出
print(e.code)
if hasattr(e, "reason"): # 如果有reason标簽,輸出
print(e.reason)
return html
重點:通過設定
headers
資訊僞裝成浏覽器向伺服器請求資料
周遊所有包含所需資訊的頁面并擷取HTML——getData函數第一部分
for i in range(0, 10): # 循環周遊10個頁面
url = baseurl + str(i * 25)
html = askURL(url)
解析HTML頁面并提取相應的資料——getData函數第二部分
# 2.解析資料
soup = BeautifulSoup(html, "html.parser")
for item in soup.find_all("div", class_="item"):
這一部分首先用
bs4
中的
BeautifulSoup
庫解析HTML為樹形結構,然後通過周遊查找所需資訊
# 影片詳情連結的比對規則
findLink = re.compile(r\'<a href="(.*?)">\')
# 影片圖檔連結的比對規則 re.S給.增加換行比對的能力
findImgSrc = re.compile(r\'<img.*src="(.*?)"\', re.S)
# 影片片名
findTitle = re.compile(r\'<span class="title">(.*)</span>\')
# 影片評分
findRating = re.compile(r\'<span class="rating_num" property="v:average">(.*)</span>\')
# 找到評價人數
findJudge = re.compile(r\'<span>(\d*)人評價</span>\')
# 找到概況
findInq = re.compile(r\'<span class="inq">(.*)</span>\')
# 找到影片的相關内容
findBd = re.compile(r\'<p class="">(.*?)</p>\', re.S)
重點:通過F12檢視豆瓣電影網站的源代碼,找出各個資訊所在的特定标簽,并且通過正規表達式的方式比對到所需資訊
按照一定格式存儲所提取的電影資訊——getData函數第三部分
data = [] # 儲存一部電影的所有資訊
item = str(item)
link = re.findall(findLink, item)[0] # 查找影片詳情連結
data.append(link)
imgSrc = re.findall(findImgSrc, item)[0] # 查找圖檔來源
data.append(imgSrc)
titles = re.findall(findTitle, item) # 片名可能有多個
if len(titles) == 2: # 分情況添加到data中
ctitle = titles[0] # 添加中文名
data.append(ctitle)
otitle = titles[1].replace("/", "") # 去掉一些無關緊要的資訊
data.append(otitle) # 添加外國名
else:
data.append(titles[0]) # 沒有外國名的時候也要添加一個空資訊
data.append(\' \') # 這樣才能保證結果輸出到表格中的時候是對齊的
rating = re.findall(findRating, item)[0] # 查找評分
data.append(rating)
judgeNum = re.findall(findJudge, item)[0] #查找打分的人數
data.append(judgeNum)
inq = re.findall(findInq, item) # 查找影片概述
if len(inq) != 0:
inq = inq[0].replace("。", "")
data.append(inq) # 添加概述
else:
data.append(" ")
bd = re.findall(findBd, item)[0] # 查找其他相關資訊
bd = re.sub(\'<br(\s+)?/>(\s+)?\', "", bd) # 去掉多餘的空格
bd = re.sub(\'/\', "", bd)
data.append(bd.strip())
datalist.append(data)
重點:當某些影片不存在相應的資訊時(例如外國名),要給添加空資料,以保證每個影片的data能對齊輸入表格中
三. 儲存資料
excel形式存儲資料—— saveDate
函數
saveDate
def saveData(datalist, savepath):
workbook = xlwt.Workbook(encoding="utf-8", style_compression=0)
worksheet = workbook.add_sheet(\'豆瓣電影Top250\', cell_overwrite_ok=True)
col = ("電影詳情連結", "圖檔連結", "影片中文名", "影片外文名", "評分", "評價人數", "概況", "相關資訊")
for i in range(0, 8): # 先輸入表格的擡頭
worksheet.write(0, i, col[i])
for i in range(0, 250):
print("第%d條錄入" % (i + 1))
data = datalist[i]
for j in range(0, 8): # 逐條錄入資訊
worksheet.write(i + 1, j, data[j])
workbook.save(savepath)
重點:給定表格的話橫縱坐标,之後輸入響應資訊即可
四.總結與反思
之前在中國大學MOOC學了python爬蟲的内容,但是因為課程比較早,是以給出的實戰案例爬取對象的網站已經不存在了,是以就想找個項目練習一下所學的知識。
本項目參考了https://www.bilibili.com/video/BV12E411A7ZQ/的相關教學
感覺總體上來說,python爬取靜态網頁并且輸出到excel還是比較簡單的,代碼量比較小而且容易上手。不過最大的問題在于這種方法隻能爬取靜态網頁,而對用JavaScript動态生成内容的網頁無能為力。希望以後能進一步學習爬取動态網頁的技術。
還有一個問題是資料雖然得到了,但是excel裡内容太繁雜了,實際看起來還不如直接去豆瓣電影的網頁看。是以爬取資料之後的展示和分析,可能也需要學習相關的技術。