豆瓣電影排行榜前250 分為10頁,第一頁的url為https://movie.douban.com/top250,但實際上應該是https://movie.douban.com/top250?start=0 後面的參數0表示從第幾個開始,如0表示從第一(肖申克的救贖)到第二十五(觸不可及),https://movie.douban.com/top250?start=25表示從第二十六(蝙蝠俠:黑暗騎士)到第五十名(死亡詩社)。等等,
是以可以用一個步長為25的range的for循環參數
for i in range(0, 250, 25):
print(i)
分析完頁面組成後,開始擷取頁面,直接request.get()發現沒有傳回任何東西,輸出一下響應碼
url = \'https://movie.douban.com/top250?start=0\'
res = request.get(url=url)
print(res.status_code)
發現傳回響應碼418

以前沒見過這個,拉網線上網查一下,發現給get裡面加一個header參數就行了
這裡可以用自己浏覽器的user-agent,如
headers = {\'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36\'}
或者用fake_agent(安裝直接用pip install fake_agent) 來為自己生成一個随機的agent添加到header字典中
from fake_useragent import UserAgent
headers = {\'User-Agent\': UserAgent().random}
之後就可以得到頁面源碼了。
然後使用lxml.etree,即xpath解析頁面源碼。用浏覽器插件xpath finder快速定位到元素
import requests
import lxml.etree as etree
url = \'https://movie.douban.com/top250?start=0\'
headers = {\'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36\'}
res = requests.get(url=url, headers=headers)
print(res.text)
html = etree.HTML(res.text)
name = html.xpath("/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1]")
print(name)
但是直接這樣子,解析到的是這樣的結果
[<Element span at 0x20b2f0cc488>]
關于這東西是什麼,有文章寫的很好:https://www.jb51.net/article/132145.htm
這裡我直接寫解決部分,在使用xpath解析時,後面加上/text()
name = html.xpath("/html/body/div[3]/div[1]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1]/text()")
解決後,再使用xpath finder插件,一步一步擷取到電影所有資料
最後把這個寫在函數裡,外面再套上一開始說的循環,就OK了
# -*- coding: utf-8 -*-
import requests
import lxml.etree as etree
def get_source(page):
url = \'https://movie.douban.com/top250?start={}\'.format(page)
headers = {
\'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36\'}
print(url)
res = requests.get(url=url, headers=headers)
print(res.status_code)
html = etree.HTML(res.text)
for i in range(1, 26):
name = html.xpath("/html/body/div[3]/div[1]/div/div[1]/ol/li[{}]/div/div[2]/div[1]/a/span[1]/text()".format(i))
info = html.xpath("/html/body/div[3]/div[1]/div/div[1]/ol/li[{}]/div/div[2]/div[2]/p[1]/text()".format(i))
score = html.xpath(
"/html/body/div[3]/div[1]/div/div[1]/ol/li[{}]/div/div[2]/div[2]/div/span[2]/text()".format(i))
slogan = html.xpath(
"/html/body/div[3]/div[1]/div/div[1]/ol/li[{}]/div/div[2]/div[2]/p[2]/span/text()".format(i))
print(name[0])
print(info[0].replace(\' \', \'\'))
print(info[1].replace(\' \', \'\'))
print(score[0])
print(slogan[0])
n = 1
for i in range(0, 250, 25):
print(\'第%d頁\' % n)
n += 1
get_source(i)
print(\'==========================================\')
在定位時,發現有4部電影介紹沒有slogan,導緻擷取到的資訊為空清單,也就導緻了list.append()會出錯。是以我加上了幾個差錯處理,解決方式可能有點傻,如果有更好的解決辦法,洗耳恭聽
代碼在最後可以看到
EXCEL儲存部分
這裡我用的xlwt
book = xlwt.Workbook()
sheet = book.add_sheet(u\'sheetname\', cell_overwrite_ok=True)
建立一個sheet表單。
資料儲存到一個大清單中,清單嵌套清單
再通過循環把資料導入到excel表單中
r = 1
for i in LIST: #有10頁
for j in i: #有25條資料
c = 2
for x in j: #有5組資料
print(x)
sheet.write(r, c, x)
c += 1
r += 1
最後在儲存一下
book.save(r\'douban.xls\')
注意檔案字尾要用xls,用xlsx會導緻檔案打不開
然後就大功告成了
打開檔案,手動加入排名,等部分資訊(這些也可以在程式裡完成,我嫌麻煩,就沒寫,直接手動來的快)
前面的✓是我自己整的,用于記錄那些看過,那些沒看過
這也是我寫這個東西的最初的目的
完整代碼在下面,僅用于參考
# -*- coding: utf-8 -*-
import requests
import lxml.etree as etree
import xlwt
def get_source(page):
List = []
url = \'https://movie.douban.com/top250?start={}\'.format(page)
headers = {
\'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36\'}
print(url)
res = requests.get(url=url, headers=headers)
print(res.status_code)
html = etree.HTML(res.text)
for i in range(1, 26):
list = []
name = html.xpath("/html/body/div[3]/div[1]/div/div[1]/ol/li[{}]/div/div[2]/div[1]/a/span[1]/text()".format(i))
info = html.xpath("/html/body/div[3]/div[1]/div/div[1]/ol/li[{}]/div/div[2]/div[2]/p[1]/text()".format(i))
score = html.xpath(
"/html/body/div[3]/div[1]/div/div[1]/ol/li[{}]/div/div[2]/div[2]/div/span[2]/text()".format(i))
slogan = html.xpath(
"/html/body/div[3]/div[1]/div/div[1]/ol/li[{}]/div/div[2]/div[2]/p[2]/span/text()".format(i))
try:
list.append(name[0])
except:
list.append(\'----\')
try:
list.append(info[0].replace(\' \', \'\').replace(\'\n\', \'\'))
except:
list.append(\'----\')
try:
list.append(info[1].replace(\' \', \'\').replace(\'\n\', \'\'))
except:
list.append(\'----\')
try:
list.append(score[0])
except:
list.append(\'----\')
try:
list.append(slogan[0])
except:
list.append(\'----\')
List.append(list)
return List
n = 1
LIST = []
for i in range(0, 250, 25):
print(\'第{}頁\'.format(n))
n += 1
List = get_source(i)
LIST.append(List)
def excel_write(LIST):
book = xlwt.Workbook()
sheet = book.add_sheet(u\'sheetname\', cell_overwrite_ok=True)
r = 1
for i in LIST: #有10頁
for j in i: #有25條資料
c = 2
for x in j: #有5組資料
print(x)
sheet.write(r, c, x)
c += 1
r += 1
book.save(r\'douban1.xls\') #儲存代碼
excel_write(LIST)