以前未登錄情況下爬取豆瓣網(wǎng)電影頁面沒遇到過限制,但最近請求頻繁時候?qū)е路祷谾orbidden 403服務(wù)器拒絕響應(yīng)的情況揩页,暫時可行的方法是正常在頁面登錄注冊旷偿,然后請求Requests攜帶header信息發(fā)送請求,適當(dāng)放慢請求頻率爆侣。
解析復(fù)制到的Request header字符串
先從瀏覽器控制臺復(fù)制到請求頭萍程,然后利用函數(shù)str2dict解析成dict格式,稍后發(fā)送請求時候需要使用到累提。
#使用headers,不使用的話頻率稍高就會返回繁忙403
header_str='''
GET /top250 HTTP/1.1
Host: movie.douban.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: https://movie.douban.com/chart
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7
Cookie: __utmc=223455111; __utmz=234495111.1512303343....106952.
'''
def str2dict(s,s1=';',s2='='):
li=s.split(s1)
res={}
for kv in li:
li2=kv.split(s2)
if len(li2)>1:
res[li2[0]]=li2[1]
return res
headers=str2dict(header_str,'\n',': ')
發(fā)送請求
發(fā)送請求獲取Top250電影名稱和年份信息
import requests
from bs4 import BeautifulSoup
import time
top250=[]
url = 'https://movie.douban.com/top250?start='
for i in range(10):
print('processing page',i)
purl = url + str(i * 25)
res = requests.get(purl,headers=headers)
soup = BeautifulSoup(res.text)
movies = soup.find_all('div', 'info')
for mov in movies:
title = mov.find('span', 'title').text
yearTag = mov.find('div', 'bd').find('p').contents[2]
year = yearTag.split('/')[0].strip()
top250.append({
'title':title,
'year':year
})
time.sleep(1)
print(len(top250),top250[:3])
直接使用API拉取JSON數(shù)據(jù)
原本豆瓣還提供了一些用于第三方開發(fā)者讀取數(shù)據(jù)的接口API尘喝,可以通過這些API直接讀取數(shù)據(jù),目前官方已經(jīng)停止這些接口的維護(hù)斋陪,是否能持續(xù)繼續(xù)使用也是未知的朽褪。
以下代碼可以一次性獲取TOP250的完整JSON格式數(shù)據(jù)置吓。
注意最后的ensure_ascii為False表示其中包含非ascii碼漢字,如果不使用ensure_ascii參數(shù)將輸出字母亂碼。
#使用API
import requests
import json
import time
top250 = []
api = 'http://api.douban.com/v2/movie/top250?start=0&count=250'
res = requests.get(api)
movies = json.loads(res.text)['subjects']
print(json.dumps(movies[0], indent=2, ensure_ascii=False))
繪制佳片的年代分布
使用plotly進(jìn)行繪圖缔赠。
import plotly.offline as py
import plotly.graph_objs as go
py.init_notebook_mode()
movies_dict={}
for mov in top250:
year=mov['year'][:4]
if year in movies_dict:
movies_dict[year]+=1
else:
movies_dict[year]=1
data=go.Bar(
x=[year for year in movies_dict],
y=[movies_dict[year] for year in movies_dict]
)
fig=go.FigureWidget([data])
fig
每個人的智能新時代
如果您發(fā)現(xiàn)文章錯誤,請不吝留言指正嗤堰;
如果您覺得有用戴质,請點(diǎn)喜歡;
如果您覺得很有用踢匣,歡迎轉(zhuǎn)載~
END