Python爬蟲入門實(shí)戰(zhàn)之貓眼電影數(shù)據(jù)抓?。▽?shí)戰(zhàn)篇)

項(xiàng)目實(shí)戰(zhàn)

靜態(tài)網(wǎng)頁實(shí)戰(zhàn)

本節(jié)我們將為大家展現(xiàn)一個(gè)完整爬蟲的大致過程,此次項(xiàng)目?jī)?nèi)容為提取貓眼電影TOP100榜中的所有電影信息并存儲(chǔ)至CSV文件中,其首頁地址為 http://maoyan.com/board/4 ,在3.2.2中我們已經(jīng)獲取過第一頁中的所有電影名了,但是如何獲取第二頁、第三頁的數(shù)據(jù)呢,即獲取第二頁第三頁對(duì)應(yīng)的URL,那么我們可以在瀏覽器中不斷翻頁尋找地址欄中URL的變化規(guī)律:

<pre class="public-DraftStyleDefault-pre" data-offset-key="99sn9-0-0" style="box-sizing: inherit; margin: 1.4em 0px; padding: calc(0.888889em); font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">

<pre class="Editable-styled" data-block="true" data-editor="f0dsm" data-offset-key="99sn9-0-0" style="box-sizing: inherit; margin: 0px; padding: 0px; font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">

第二頁: http://maoyan.com/board/4?offset=10

第三頁: http://maoyan.com/board/4?offset=20

第四頁: http://maoyan.com/board/4?offset=30

......

</pre>

</pre>

我們看見URL的改變規(guī)律就是參數(shù)offset值不斷偏移,每頁偏移的值為10,由此我們可以編寫一個(gè)獲取每頁數(shù)據(jù)函數(shù),接收參數(shù)就是頁碼數(shù):

<pre class="public-DraftStyleDefault-pre" data-offset-key="b5aka-0-0" style="box-sizing: inherit; margin: 1.4em 0px; padding: calc(0.888889em); font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">

<pre class="Editable-styled" data-block="true" data-editor="f0dsm" data-offset-key="b5aka-0-0" style="box-sizing: inherit; margin: 0px; padding: 0px; font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">

import requests

headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'

}

偏移參數(shù),默認(rèn)為0,即為第一頁

params = {

'offset': 0

}

def get_html(page):

'''

獲取一頁html頁面

:param page: 頁數(shù)

:return: 該頁html頁面

'''

params['offset'] = page * 10

url = ' http://maoyan.com/board/4'

try:

response = requests.get(url, headers=headers, params=params)

if response.status_code == 200:

html = response.text

return html

else:

return -1

except:

return None

</pre>

</pre>

當(dāng)我們獲取到html頁面后,就可以提取相應(yīng)的電影信息了,比如榜單張每一項(xiàng)電影都會(huì)有的屬性:電影名稱,主演,上映時(shí)間,評(píng)分等信息。提取信息有多種方式,下面我們利用正則表達(dá)式提取電影信息:

<pre class="public-DraftStyleDefault-pre" data-offset-key="2m0hr-0-0" style="box-sizing: inherit; margin: 1.4em 0px; padding: calc(0.888889em); font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">

<pre class="Editable-styled" data-block="true" data-editor="f0dsm" data-offset-key="2m0hr-0-0" style="box-sizing: inherit; margin: 0px; padding: 0px; font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">

def parse_infor(html):

'''

提取html頁面中的電影信息

:param html: html頁面

:return: 電影信息列表

'''

編寫正則字符串規(guī)則,提取 電影名,主演,上映時(shí)間,評(píng)分信息

pat = re.compile('<div class="movie-item-info">. ?<p. ?><a. ?>(. ?)</a></p>. ?<p. ?>(. ?)</p>.?<p. ?>(. ?)</p>. ?</div>. ?<div. ?>. ?<p. ?><i. ?>(. ?)</i><i. ?>(. ?)</i></p>. ?</div>. ?</div>. ?</div>', re.S)

得到一個(gè)二重列表

results = re.findall(pat, html)

one_page_film = []

if results:

for result in results:

film_dict = {}

獲取電影名信息

film_dict['name'] = result[0]

獲取主演信息

start = result[1]

替換字符串中的 '\n' 字符,即換行字符

start.replace('\n', '')

去掉字符串兩邊的空格,并使用切片去除字符串開頭的'主演:'三個(gè)字符

start = start.strip()[3:]

film_dict['start'] = start

獲取上映時(shí)間信息

releasetime = result[2]

使用切片去除字符串開頭的'上映時(shí)間:'五個(gè)字符

releasetime = releasetime[5:]

film_dict['releasetime'] = releasetime

獲取評(píng)分信息,由于評(píng)分是有兩個(gè)字符拼接的,這里我們提取后也需要進(jìn)行拼接操作

left_half =result[3]

right_half = result[4]

score = left_half + right_half

film_dict['score'] = score

打印該電影信息:

print(film_dict)

將該電影信息字典存入一頁電影列表中

one_page_film.append(film_dict)

return one_page_film

else:

return None

</pre>

</pre>

不熟悉正則讀者要好好復(fù)習(xí)下前面的知識(shí),雖然正則寫起來可能會(huì)麻煩些,當(dāng)時(shí)他的提取效率是最高的,接下來我們就可以將提取好的電影信息進(jìn)行存儲(chǔ)操作,這里我們存儲(chǔ)為CSV文件:

<pre class="public-DraftStyleDefault-pre" data-offset-key="7cmg0-0-0" style="box-sizing: inherit; margin: 1.4em 0px; padding: calc(0.888889em); font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">

<pre class="Editable-styled" data-block="true" data-editor="f0dsm" data-offset-key="7cmg0-0-0" style="box-sizing: inherit; margin: 0px; padding: 0px; font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">

def save_infor(one_page_film):

'''

存儲(chǔ)提取好的電影信息

:param html: 電影信息列表

:return: None

'''

with open('top_film.csv', 'a', newline='') as f:

csv_file = csv.writer(f)

for one in one_page_film:

csv_file.writerow([one['name'], one['start'], one['releasetime'], one['score']])

</pre>

</pre>

以上是獲取一頁html頁面并提取電影信息存儲(chǔ)至CSV中的過程,接下來我們構(gòu)造十頁的URL便可以完成貓眼電影TOP100榜中的所有電影信息的獲取和存儲(chǔ)了,以下是完整程序:

<pre class="public-DraftStyleDefault-pre" data-offset-key="ap1fk-0-0" style="box-sizing: inherit; margin: 1.4em 0px; padding: calc(0.888889em); font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">

<pre class="Editable-styled" data-block="true" data-editor="f0dsm" data-offset-key="ap1fk-0-0" style="box-sizing: inherit; margin: 0px; padding: 0px; font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">

import requests

import re

import csv

import time

headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'

}

params = {

'offset': 0

}

def get_html(page):

'''

獲取一頁html頁面

:param page: 頁數(shù)

:return: 該頁html頁面

'''

params['offset'] = page * 10

url = ' http://maoyan.com/board/4'

try:

response = requests.get(url, headers=headers, params=params)

if response.status_code == 200:

html = response.text

return html

else:

return -1

except:

return None

def parse_infor(html):

'''

提取html頁面中的電影信息

:param html: html頁面

:return: 電影信息列表

'''

pat = re.compile('<div class="movie-item-info">. ?<p. ?><a. ?>(. ?)</a></p>. ?<p. ?>(. ?)</p>.?<p. ?>(. ?)</p>. ?</div>. ?<div. ?>. ?<p. ?><i. ?>(. ?)</i><i. ?>(. ?)</i></p>. ?</div>. ?</div>. ?</div>', re.S)

results = re.findall(pat, html)

one_page_film = []

if results:

for result in results:

film_dict = {}

獲取電影名信息

film_dict['name'] = result[0]

獲取主演信息

start = result[1]

替換字符串中的 '\n' 字符,即換行字符

start.replace('\n', '')

去掉字符串兩邊的空格,并使用切片去除字符串開頭的'主演:'三個(gè)字符

start = start.strip()[3:]

film_dict['start'] = start

獲取上映時(shí)間信息

releasetime = result[2]

使用切片去除字符串開頭的'上映時(shí)間:'五個(gè)字符

releasetime = releasetime[5:]

film_dict['releasetime'] = releasetime

獲取評(píng)分信息

left_half =result[3]

right_half = result[4]

score = left_half + right_half

film_dict['score'] = score

打印該電影信息:

print(film_dict)

將該電影信息字典存入一頁電影列表中

one_page_film.append(film_dict)

return one_page_film

else:

return None

def save_infor(one_page_film):

'''

存儲(chǔ)提取好的電影信息

:param one_page_film: 電影信息列表

:return: None

'''

with open('top_film.csv', 'a', newline='', errors='ignore') as f:

csv_file = csv.writer(f)

for one in one_page_film:

csv_file.writerow([one['name'], one['start'], one['releasetime'], one['score']])

if name == " main ":

利用循環(huán)構(gòu)建頁碼

for page in range(10):

請(qǐng)求頁面

html = get_html(page)

if html:

提取信息

one_page_film = parse_infor(html)

if one_page_film:

存儲(chǔ)信息

save_infor(one_page_film)

time.sleep(1)

</pre>

</pre>

動(dòng)態(tài)網(wǎng)頁實(shí)戰(zhàn)

本節(jié)我們將爬取貓眼電影實(shí)時(shí)票房數(shù)據(jù),學(xué)會(huì)在動(dòng)態(tài)網(wǎng)頁中獲取我們想要的數(shù)據(jù),首先打開貓眼專業(yè)版-實(shí)時(shí)票房, 其網(wǎng)址為: https://piaofang.maoyan.com/dashboard ,然后我們可以看見現(xiàn)在的實(shí)時(shí)電影票房數(shù)據(jù),可以看見 “今日實(shí)時(shí)” 的數(shù)據(jù)在不斷地動(dòng)態(tài)增加:

image

image

而當(dāng)我們查看該網(wǎng)頁源代碼時(shí),卻并沒有電影相關(guān)的票房等信息,那么可以判斷該頁面可能使用了Ajax(即“Asynchronous Javascript And XML”(異步 JavaScript 和 XML))技術(shù),即動(dòng)態(tài)網(wǎng)頁(是指跟靜態(tài)網(wǎng)頁相對(duì)的一種網(wǎng)頁編程技術(shù)。靜態(tài)網(wǎng)頁,隨著html代碼的生成,頁面的內(nèi)容和顯示效果就基本上不會(huì)發(fā)生變化了——除非你修改頁面代碼。而動(dòng)態(tài)網(wǎng)頁則不然,頁面代碼雖然沒有變,但是顯示的內(nèi)容卻是可以隨著時(shí)間、環(huán)境或者數(shù)據(jù)庫操作的結(jié)果而發(fā)生改變)。我們可以利用瀏覽器的開發(fā)者工具進(jìn)行分析:

image

image

我們可以發(fā)現(xiàn)每隔一段時(shí)間都會(huì)有一個(gè)新的請(qǐng)求,其請(qǐng)求類型都為xhr,而Ajax的請(qǐng)求類型就是xhr,這請(qǐng)求可能就是實(shí)時(shí)更新的票房信息,而我們需要的數(shù)據(jù)可能就在這些文件里,于是我們選擇一個(gè)進(jìn)行分析:

image

image

在Preview中,我們可以看見大量的電影相關(guān)的信息,即我們想要獲取的實(shí)時(shí)電影票房數(shù)據(jù),而這些內(nèi)容是JSON格式的,瀏覽器開發(fā)者工具自動(dòng)做了解析方便我們查看,接下來我們只需要用Python模擬這些Ajax請(qǐng)求,拿下這些數(shù)據(jù)然后解析即可,而這些Ajax無非依然是HTTP請(qǐng)求,所以只要拿到對(duì)應(yīng)URL然后使用Python模擬該請(qǐng)求即可,我們可以直接復(fù)制,如下圖:

image

image

獲取到該請(qǐng)求的鏈接,接下來我們就用Python模擬該請(qǐng)求:

<pre class="public-DraftStyleDefault-pre" data-offset-key="2jmdt-0-0" style="box-sizing: inherit; margin: 1.4em 0px; padding: calc(0.888889em); font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">

<pre class="Editable-styled" data-block="true" data-editor="f0dsm" data-offset-key="2jmdt-0-0" style="box-sizing: inherit; margin: 0px; padding: 0px; font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">

headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'

}

def get_html():

'''

獲取JSON文件

:return: JSON格式的數(shù)據(jù)

'''

請(qǐng)求second.json的URL

url = ' https://box.maoyan.com/promovie/api/box/second.json'

try:

response = requests.get(url, headers=headers)

if response.status_code == 200:

由于是JSON文件,我們可以返回JSON格式的數(shù)據(jù)便于后續(xù)提取

return response.json()

else:

return -1

except:

return None

</pre>

</pre>

獲取對(duì)應(yīng)的JSON數(shù)據(jù)后,我們就可以利用進(jìn)行提取操作了。

<pre class="public-DraftStyleDefault-pre" data-offset-key="1f72a-0-0" style="box-sizing: inherit; margin: 1.4em 0px; padding: calc(0.888889em); font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">

<pre class="Editable-styled" data-block="true" data-editor="f0dsm" data-offset-key="1f72a-0-0" style="box-sizing: inherit; margin: 0px; padding: 0px; font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">

def parse_infor(json):

'''

從JSON數(shù)據(jù)中提取電影票房數(shù)據(jù),包括:電影名,上映信息,綜合票房,票房占比,累計(jì)票房

:param json: JSON格式的數(shù)據(jù)

:return: 每次循環(huán)返回一次字典類型的電影數(shù)據(jù)

'''

if json:

利用json中的get()方法層層獲取對(duì)應(yīng)的信息

items = json.get('data').get('list')

for item in items:

piaofang = {}

piaofang['電影名'] = item.get('movieName')

piaofang['上映信息'] = item.get('releaseInfo')

piaofang['綜合票房'] = item.get('boxInfo')

piaofang['票房占比'] = item.get('boxRate')

piaofang['累計(jì)票房'] = item.get('sumBoxInfo')

利用生成器每次循環(huán)都返回一個(gè)數(shù)據(jù)

yield piaofang

else:

return None

</pre>

</pre>

讀者可能看見我們沒有使用常規(guī)的return進(jìn)行函數(shù)返回,而是使用了生成器,這樣就能每次循環(huán)都返回一次數(shù)據(jù),具體讀者可以 生成器 | 廖雪峰的官方網(wǎng)站 進(jìn)一步了解學(xué)習(xí),接下來我們就將提取好的票房信息存儲(chǔ)為格式化的HTML文件:

<pre class="public-DraftStyleDefault-pre" data-offset-key="b5r5l-0-0" style="box-sizing: inherit; margin: 1.4em 0px; padding: calc(0.888889em); font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">

<pre class="Editable-styled" data-block="true" data-editor="f0dsm" data-offset-key="b5r5l-0-0" style="box-sizing: inherit; margin: 0px; padding: 0px; font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">

def save_infor(results):

'''

存儲(chǔ)格式化的電影票房數(shù)據(jù)HTML文件

:param results: 電影票房數(shù)據(jù)的生成器

:return: None

'''

rows = ''

for piaofang in results:

利用Python中的format字符串填充html表格中的內(nèi)容

row = '<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td></tr>'.format(piaofang['電影名'],

piaofang['上映信息'],

piaofang['綜合票房'],

piaofang['票房占比'],

piaofang['累計(jì)票房'])

利用字符串拼接循環(huán)存儲(chǔ)每個(gè)格式化的電影票房信息

rows = rows + '\n' + row

利用字符串拼接處格式化的HTML頁面

piaofang_html = '''

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>電影票房</title>

</head>

<body>

<style>

.table1_5 table {

width:100%;

margin:15px 0

}

.table1_5 th {

background-color:#00BFFF;

color:#FFFFFF

}

.table1_5,.table1_5 th,.table1_5 td

{

font-size:0.95em;

text-align:center;

padding:4px;

border:1px solid #dddddd;

border-collapse:collapse

}

.table1_5 tr:nth-child(odd){

background-color:#aae9fe;

}

.table1_5 tr:nth-child(even){

background-color:#fdfdfd;

}

</style>

<table class='table1_5'>

<tr>

<th>電影名</th>

<th>上映信息</th>

<th>綜合票房</th>

<th>票房占比</th>

<th>累計(jì)票房</th>

</tr>

''' + rows + '''

</table>

</body>

</html>

'''

存儲(chǔ)已經(jīng)格式化的html頁面

with open('piaofang.html', 'w', encoding='utf-8') as f:

f.write(piaofang_html)

</pre>

</pre>

我們將以上過程整合,即可得到完整的票房數(shù)據(jù)獲取的代碼實(shí)例:

<pre class="public-DraftStyleDefault-pre" data-offset-key="bd99b-0-0" style="box-sizing: inherit; margin: 1.4em 0px; padding: calc(0.888889em); font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">

<pre class="Editable-styled" data-block="true" data-editor="f0dsm" data-offset-key="bd99b-0-0" style="box-sizing: inherit; margin: 0px; padding: 0px; font-size: 0.9em; word-break: initial; overflow-wrap: initial; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;">

import requests

headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'

}

def get_html():

'''

獲取JSON文件

:return: JSON格式的數(shù)據(jù)

'''

請(qǐng)求second.json的URL

url = ' https://box.maoyan.com/promovie/api/box/second.json'

try:

response = requests.get(url, headers=headers)

if response.status_code == 200:

由于是JSON文件,我們可以返回JSON格式的數(shù)據(jù)便于后續(xù)提取

return response.json()

else:

return -1

except:

return None

def parse_infor(json):

'''

從JSON數(shù)據(jù)中提取電影票房數(shù)據(jù),包括:電影名,上映信息,綜合票房,票房占比,累計(jì)票房

:param json: JSON格式的數(shù)據(jù)

:return: 每次循環(huán)返回一次字典類型的電影數(shù)據(jù)

'''

if json:

利用json中的get()方法層層獲取對(duì)應(yīng)的信息

items = json.get('data').get('list')

for item in items:

piaofang = {}

piaofang['電影名'] = item.get('movieName')

piaofang['上映信息'] = item.get('releaseInfo')

piaofang['綜合票房'] = item.get('boxInfo')

piaofang['票房占比'] = item.get('boxRate')

piaofang['累計(jì)票房'] = item.get('sumBoxInfo')

利用生成器每次循環(huán)都返回一個(gè)數(shù)據(jù)

yield piaofang

else:

return None

def save_infor(results):

'''

存儲(chǔ)格式化的電影票房數(shù)據(jù)HTML文件

:param results: 電影票房數(shù)據(jù)的生成器

:return: None

'''

rows = ''

for piaofang in results:

利用Python中的format字符串填充html表格中的內(nèi)容

row = '<tr><td>{}</td><td>{}</td><td>{}</td><td>{}</td><td>{}</td></tr>'.format(piaofang['電影名'],

piaofang['上映信息'],

piaofang['綜合票房'],

piaofang['票房占比'],

piaofang['累計(jì)票房'])

利用字符串拼接循環(huán)存儲(chǔ)每個(gè)格式化的電影票房信息

rows = rows + '\n' + row

利用字符串拼接處格式化的HTML頁面

piaofang_html = '''

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>電影票房</title>

</head>

<body>

<style>

.table1_5 table {

width:100%;

margin:15px 0

}

.table1_5 th {

background-color:#00BFFF;

color:#FFFFFF

}

.table1_5,.table1_5 th,.table1_5 td

{

font-size:0.95em;

text-align:center;

padding:4px;

border:1px solid #dddddd;

border-collapse:collapse

}

.table1_5 tr:nth-child(odd){

background-color:#aae9fe;

}

.table1_5 tr:nth-child(even){

background-color:#fdfdfd;

}

</style>

<table class='table1_5'>

<tr>

<th>電影名</th>

<th>上映信息</th>

<th>綜合票房</th>

<th>票房占比</th>

<th>累計(jì)票房</th>

</tr>

''' + rows + '''

</table>

</body>

</html>

'''

存儲(chǔ)已經(jīng)格式化的html頁面

with open('piaofang.html', 'w', encoding='utf-8') as f:

f.write(piaofang_html)

if name == " main ":

獲取信息

json = get_html()

提取信息

results = parse_infor(json)

存儲(chǔ)信息

save_infor(results)

</pre>

</pre>

HTML文件存儲(chǔ)效果如下圖所示:

image

image

可以看見,動(dòng)態(tài)網(wǎng)頁的爬蟲可能會(huì)更加簡(jiǎn)單些,關(guān)鍵就在于找到對(duì)應(yīng)的XHR格式的請(qǐng)求,而一般這種格式的文件都是JSON格式的,提取相對(duì)也會(huì)更加簡(jiǎn)單方便,而讀者可能會(huì)問為何要把這個(gè)信息存儲(chǔ)為HTML文件格式的呢,喜歡電影的讀者可能會(huì)經(jīng)常打開貓眼電影查看每天的電影票房數(shù)據(jù),何不嘗試將我們所學(xué)的爬蟲知識(shí)運(yùn)用起來制作一個(gè)定時(shí)爬取電影票房數(shù)據(jù)并推送至個(gè)人郵箱的爬蟲小程序呢,這樣就省得我們每天打開網(wǎng)頁查看,讓數(shù)據(jù)主動(dòng)為我們服務(wù),也算是學(xué)習(xí)致用了吧,感興趣的讀者可以自己嘗試下,下圖筆者根據(jù)這個(gè)爬蟲程序擴(kuò)展每天收到的實(shí)時(shí)票房信息郵件,每天定時(shí)爬取推送給筆者,列表內(nèi)容如下圖所示:

image

image

推動(dòng)內(nèi)容如下圖所示:

image

image

因?yàn)猷]箱定時(shí)推送會(huì)涉及郵箱設(shè)置、郵箱模塊使用和不同系統(tǒng)(Linux和Windows)定時(shí)任務(wù)的部署等諸多環(huán)節(jié),感覺會(huì)有些偏題,畢竟這是一篇爬蟲入門方面的文章

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容