【Python爬蟲&資料分析】2018年電影,你看了幾部?
本文轉自公眾號:[ 法納斯特]
12月已開始了,離2018年的結束也就半個多月的時間了,還記得年初立下的flag嗎?
完成了多少?相信很多人和我一樣,抱頭痛哭...
本次利用貓眼電影,實現對2018年的電影大資料進行分析。
/ 01 / 網頁分析
01 標籤
透過點選貓眼電影已經歸類好的標籤,得到網址資訊。
02 索引頁
開啟開發人員工具,獲取索引頁裡電影的連結以及評分資訊。
索引頁一共有30多頁,但是有電影評分的只有10頁。
本次只對有電影評分的資料進行獲取。
03 詳情頁
對詳情頁的資訊進行獲取。
主要是名稱,型別,國家,時長,上映時間,評分,評分人數,累計票房。
/ 02 / 反爬破解
透過開發人員工具發現,貓眼針對評分,評分人數,累計票房的資料,施加了文字反爬。
透過檢視網頁原始碼,發現只要重新整理頁面,三處文字編碼就會改變,無法直接匹配資訊。
所以需要下載文字檔案,對其進行雙匹配。
from fontTools.ttLib import TTFont
#font = TTFont('base.woff')
#font.saveXML('base.xml')
font = TTFont('maoyan.woff')
font.saveXML('maoyan.xml')
將woff格式轉換為xml格式,以便在Pycharm中檢視詳細資訊。
利用下面這個網站,開啟woff檔案。
url:
可以得到下面數字部分資訊(上下兩塊)。
在Pycharm中檢視xml格式檔案(左右兩塊),你就會發現有對應資訊。
透過上圖你就可以將數字6對上號了,其他數字一樣的。
def get_numbers(u):
"""
對貓眼的文字反爬進行破解
"""
cmp = re.compile(",\n url\('(//.*.woff)'\) format\('woff'\)")
rst = cmp.findall(u)
ttf = requests.get("http:" + rst[0], stream=True)
with open("maoyan.woff", "wb") as pdf:
for chunk in ttf.iter_content(chunk_size=1024):
if chunk:
pdf.write(chunk)
base_font = TTFont('base.woff')
maoyanFont = TTFont('maoyan.woff')
maoyan_unicode_list = maoyanFont['cmap'].tables[0].ttFont.getGlyphOrder()
maoyan_num_list = []
base_num_list = ['.', '3', '0', '8', '9', '4', '1', '5', '2', '7', '6']
base_unicode_list = ['x', 'uniF561', 'uniE6E1', 'uniF125', 'uniF83F', 'uniE9E2', 'uniEEA6', 'uniEEC2', 'uniED38', 'uniE538', 'uniF8E7']
for i in range(1, 12):
maoyan_glyph = maoyanFont['glyf'][maoyan_unicode_list[i]]
for j in range(11):
base_glyph = base_font['glyf'][base_unicode_list[j]]
if maoyan_glyph == base_glyph:
maoyan_num_list.append(base_num_list[j])
break
maoyan_unicode_list[1] = 'uni0078'
utf8List = [eval(r"'\u" + uni[3:] + "'").encode("utf-8") for uni in maoyan_unicode_list[1:]]
utf8last = []
for i in range(len(utf8List)):
utf8List[i] = str(utf8List[i], encoding='utf-8')
utf8last.append(utf8List[i])
return (maoyan_num_list ,utf8last)
/ 03 / 資料獲取
01 構造請求頭
head = """
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:maoyan.com
Upgrade-Insecure-Requests:1
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36
"""
def str_to_dict(header):
"""
構造請求頭,可以在不同函式里構造不同的請求頭
"""
header_dict = {}
header = header.split('\n')
for h in header:
h = h.strip()
if h:
k, v = h.split(':', 1)
header_dict[k] = v.strip()
return header_dict
因為索引頁和詳情頁請求頭不一樣,這裡為了簡便,構造了一個函式。
02 獲取電影詳情頁連結
def get_url():
"""
獲取電影詳情頁連結
"""
for i in range(0, 300, 30):
time.sleep(10)
url = ' + str(i)
host = """Referer:
"""
header = head + host
headers = str_to_dict(header)
response = requests.get(url=url, headers=headers)
html = response.text
soup = BeautifulSoup(html, 'html.parser')
data_1 = soup.find_all('div', {'class': 'channel-detail movie-item-title'})
data_2 = soup.find_all('div', {'class': 'channel-detail channel-detail-orange'})
num = 0
for item in data_1:
num += 1
time.sleep(10)
url_1 = item.select('a')[0]['href']
if data_2[num-1].get_text() != '暫無評分':
url = ' + url_1
for message in get_message(url):
print(message)
to_mysql(message)
print(url)
print('---------------^^^Film_Message^^^-----------------')
else:
print('The Work Is Done')
break
03 獲取電影詳情頁資訊
def get_message(url):
"""
獲取電影詳情頁裡的資訊
"""
time.sleep(10)
data = {}
host = """refer:
"""
header = head + host
headers = str_to_dict(header)
response = requests.get(url=url, headers=headers)
u = response.text
# 破解貓眼文字反爬
(mao_num_list, utf8last) = get_numbers(u)
# 獲取電影資訊
soup = BeautifulSoup(u, "html.parser")
mw = soup.find_all('span', {'class': 'stonefont'})
score = soup.find_all('span', {'class': 'score-num'})
unit = soup.find_all('span', {'class': 'unit'})
ell = soup.find_all('li', {'class': 'ellipsis'})
name = soup.find_all('h3', {'class': 'name'})
# 返回電影資訊
data["name"] = name[0].get_text()
data["type"] = ell[0].get_text()
data["country"] = ell[1].get_text().split('/')[0].strip().replace('\n', '')
data["length"] = ell[1].get_text().split('/')[1].strip().replace('\n', '')
data["released"] = ell[2].get_text()[:10]
# 因為會出現沒有票房的電影,所以這裡需要判斷
if unit:
bom = ['分', score[0].get_text().replace('.', '').replace('萬', ''), unit[0].get_text()]
for i in range(len(mw)):
moviewish = mw[i].get_text().encode('utf-8')
moviewish = str(moviewish, encoding='utf-8')
# 透過比對獲取反爬文字資訊
for j in range(len(utf8last)):
moviewish = moviewish.replace(utf8last[j], maoyan_num_list[j])
if i == 0:
data["score"] = moviewish + bom[i]
elif i == 1:
if '萬' in moviewish:
data["people"] = int(float(moviewish.replace('萬', '')) * 10000)
else:
data["people"] = int(float(moviewish))
else:
if '萬' == bom[i]:
data["box_office"] = int(float(moviewish) * 10000)
else:
data["box_office"] = int(float(moviewish) * 100000000)
else:
bom = ['分', score[0].get_text().replace('.', '').replace('萬', ''), 0]
for i in range(len(mw)):
moviewish = mw[i].get_text().encode('utf-8')
moviewish = str(moviewish, encoding='utf-8')
for j in range(len(utf8last)):
moviewish = moviewish.replace(utf8last[j], maoyan_num_list[j])
if i == 0:
data["score"] = moviewish + bom[i]
else:
if '萬' in moviewish:
data["people"] = int(float(moviewish.replace('萬', '')) * 10000)
else:
data["people"] = int(float(moviewish))
data["box_office"] = bom[2]
yield data
/ 04 / 資料儲存
01 建立資料庫及表格
db = pymysql.connect(host='127.0.0.1', user='root', password='774110919', port=3306)
cursor = db.cursor()
cursor.execute("CREATE DATABASE maoyan DEFAULT CHARACTER SET utf8mb4")
db.close()
db = pymysql.connect(host='127.0.0.1', user='root', password='774110919', port=3306, db='maoyan')
cursor = db.cursor()
sql = 'CREATE TABLE IF NOT EXISTS films (name VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, country VARCHAR(255) NOT NULL, length VARCHAR(255) NOT NULL, released VARCHAR(255) NOT NULL, score VARCHAR(255) NOT NULL, people INT NOT NULL, box_office BIGINT NOT NULL, PRIMARY KEY (name))'
cursor.execute(sql)
db.close()
其中票房收入資料型別為BIGINT(19位數),最大為18446744073709551615。
INT(10位數),最大為2147483647,達不到36億(3600000000)。
02 資料儲存
def to_mysql(data):
"""
資訊寫入mysql
"""
table = 'films'
keys = ', '.join(data.keys())
values = ', '.join(['%s'] * len(data))
db = pymysql.connect(host='localhost', user='root', password='774110919', port=3306, db='maoyan')
cursor = db.cursor()
sql = 'INSERT INTO {table}({keys}) VALUES ({values})'.format(table=table, keys=keys, values=values)
try:
if cursor.execute(sql, tuple(data.values())):
print("Successful")
db.commit()
except:
print('Failed')
db.rollback()
db.close()
最後成功儲存資料
/ 05 / 資料視覺化
視覺化原始碼就不放了,公眾號回覆電影即可獲得。
01 電影票房TOP10
還剩一個多月,不知道榜單上會不會有新成員。最近「毒液」很火,蠻有希望。
02 電影評分TOP10
這裡就得吐槽一下pyecharts,座標轉換後,座標值名稱太長就會被遮擋,還需改進呢~
03 電影人氣TOP10
茫茫人海之中,相信一定也有大家的身影,我也是其中的一員!!!
04 每月電影上映數量
每月上映數好像沒什麼大差距,7月最少,難道是因為天氣熱?
05 每月電影票房
這裡就看出春節檔電影的威力了,金三銀四、金九銀十,各行各業的規律,電影行業也不例外。
上一張圖我們知道7月份電影上新最少,票房反而是第二。
這裡看了下資料,發現有「我不是藥神」「西虹市首富」「邪不壓正」「摩天營救」「狄仁傑之四大天王」幾部大劇撐著。
06 各國家電影數量TOP10
原來中國電影這麼高產的,可是豆瓣TOP250裡又有多少中國電影呢?深思!!!
07 中外票房對比
2017年的年度票房是560億,估計今年快要突破了。據說今年全年票房有望突破600億。
08 電影名利雙收TOP10
計算公式是,把某部電影的評分在所有電影評分中的排名與這部電影的票房在所有票房中的排名加起來,再除以電影總數。
除了「侏羅紀世界2」「無雙」「捉妖記2」,我都看過啦!
09 電影叫座不叫好TOP10
計算公式是,把某部電影的票房排名減去某部電影的評分排名加起來,再除以電影總數。
可能是貓眼的使用者比較仁慈吧,與豆瓣相比,普遍評分都比較高。我個人都不太敢相信這個結果。
不過有一個還是挺準的,「愛情公寓」。
10 電影型別分佈
劇情電影永遠引人深思。感覺今年的電影好多跟錢有關,比如「我不是藥神」「西虹市首富」「一出好戲」「頭號玩家」,貧窮限制了大傢伙們。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31562041/viewspace-2284413/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- python爬蟲 爬取豆瓣電影 1-10 ajax 資料Python爬蟲
- 爬蟲如何爬取貓眼電影TOP榜資料爬蟲
- Python 爬蟲實戰(1):分析豆瓣中最新電影的影評Python爬蟲
- 31部黑客電影 你看過哪幾部?黑客
- 【python爬蟲案例】利用python爬取豆瓣電影TOP250評分排行資料!Python爬蟲
- 躁動不安的年代,你需要讀幾本好書(python爬蟲及資料分析)Python爬蟲
- Python電影爬蟲之身體每況愈下Python爬蟲
- python初級爬蟲之貓眼電影Python爬蟲
- Python爬蟲批次下載電影連結Python爬蟲
- python爬蟲總是爬不到資料,你需要解決反爬蟲了Python爬蟲
- 8個Python爬蟲框架,你知道幾個?Python爬蟲框架
- python爬蟲利用代理IP分析大資料Python爬蟲大資料
- Python爬蟲筆記(4):利用scrapy爬取豆瓣電影250Python爬蟲筆記
- Python爬蟲教程-17-ajax爬取例項(豆瓣電影)Python爬蟲
- 擼個爬蟲,爬取電影種子爬蟲
- Python爬蟲例項:爬取貓眼電影——破解字型反爬Python爬蟲
- Python爬蟲入門實戰之貓眼電影資料抓取(理論篇)Python爬蟲
- Python爬蟲入門實戰之貓眼電影資料抓取(實戰篇)Python爬蟲
- scrapy 爬電影 抓取資料
- 爬取豆瓣電影Top250和資料分析
- python更換代理爬取豆瓣電影資料Python
- Python爬取分析豆瓣電影Top250Python
- scrapy爬取豆瓣電影資料
- Python爬蟲之小說資訊爬取與資料視覺化分析Python爬蟲視覺化
- Python 爬蟲實戰之爬拼多多商品並做資料分析Python爬蟲
- 用Python爬蟲分析演唱會銷售資料Python爬蟲
- 爬蟲01:爬取豆瓣電影TOP 250基本資訊爬蟲
- 利用Python爬蟲爬取天氣資料Python爬蟲
- 豆瓣電影TOP250爬蟲及視覺化分析筆記爬蟲視覺化筆記
- Python爬取電影天堂Python
- 【Python】從0開始寫爬蟲——轉身扒豆瓣電影Python爬蟲
- Python爬蟲學習-大資料統計分析(基礎)Python爬蟲大資料
- 資料分析專案(一)——爬蟲篇爬蟲
- python爬蟲是什麼?爬蟲可以分為哪幾類?Python爬蟲
- 【Python學習】爬蟲爬蟲爬蟲爬蟲~Python爬蟲
- 一篇文章教會你利用Python網路爬蟲實現豆瓣電影採集Python爬蟲
- Python爬蟲之資料解析(XPath)Python爬蟲
- Python【爬蟲實戰】提取資料Python爬蟲