在本篇博客中,我们将使用requests+正则表达式来爬取猫眼电影官网的TOP100电影榜单,获取每部电影的片名,主演,上映日期,评分和封面等内容。
打开猫眼Top100,分析URL的变化:发现Top100榜总共包含10页,每页10部电影,并且每一页的URL都是有规律的,如第2页为https://maoyan.com/board/4?offset=10,第三页为https://maoyan.com/board/4?offset=20。由此可得第n页为https://maoyan.com/board/4?offset=(n-1)*10。接下来我们通过爬虫四部曲,来对其进行爬取:
首先搭建起程序的主题框架:
import csv
import json
import time
import re
import requests
from requests import RequestException
def get_one_page(url):
pass
def parse_one_page(html):
pass
def write_tofile(content):
pass
if __name__ == '__main__':
for i in range(10):
url = 'https://maoyan.com/board/4?offset='+str(i*10)
#发送请求 获取响应
html = get_one_page(url)
#解析响应内容
content = parse_one_page(html)
#数据存储
write_tofile(content)
#每个页面间隔1s
time.sleep(1)
然后逐一补全上述函数。首先是请求页面的函数:
def get_one_page(url):
try:
#添加User-Agent,放在headers中,伪装成浏览器
headers = {
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}
response = requests.get(url,headers=headers)
if response.status_code == 200:
response.encoding = response.apparent_encoding
return response.text
return None
except RequestException:
return None
其中User-Agent的值,可以打开Chrome浏览器,随便打开一个页面,右键检查,在Network中打开一个请求,在Headers中便可以找到,把值直接copy过去就好。
然后编写页面解析函数,首先用Chrome打开Top100榜页面,右键检查,在element选项卡中定位页面元素:
点击左上方的箭头图标,此时将鼠标移动到页面的任意位置,该位置对应的html代码就会在Elements中被定位,退出箭头模式可以按esc。我们发现每部电影都被包含在dd标签中,所有我们想要的信息也都在其中:
接下来我们可以把dd标签内所有的html代码全部copy下来,把冗余的部分用.*?过滤掉,留一些标识来帮助我们定位想要的信息,把想要的信息放在(.*?)中,进行提取:
def parse_one_page(html):
pattern = re.compile('.*?board-index.*?">(.*?)' #序号
+'.*?data-src="(.*?)"' #图片地址
+'.*?class="name">(.*?)' #影片名
+'.*?class="star">(.*?)' #主演
+'.*?class="releasetime">(.*?)'#上映时间
+'.*?class="score">(.*?)'#评分整数
+'.*?class="fraction">(.*?)'#评分小数
+'.*? ',re.S)
items = pattern.findall(html) #返回一个数组
content = []
for item in items:
content.append({
'index':item[0],
'image':item[1],
'title':item[2],
'actor':item[3],
'time':item[4],
'score':item[5]+item[6]
})
return content
最后进行数据存储:
def write_tofile(content):
'''
#存为json形式文本文件
# for item in content:
# with open('result.txt','a',encoding='utf-8') as f:
# f.write(json.dumps(item,ensure_ascii=False)+'\n')
'''
#存为csv文件
for item in content:
print(item)
with open('result.csv','a',encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow([item['index'],item['image'],item['title'],item['actor'],item['time'],item['score']])
f.close()
完整代码:
import csv
import json
import time
import re
import requests
from requests import RequestException
def get_one_page(url):
try:
#添加User-Agent,放在headers中,伪装成浏览器
headers = {
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}
response = requests.get(url,headers=headers)
if response.status_code == 200:
response.encoding = response.apparent_encoding
return response.text
return None
except RequestException:
return None
def parse_one_page(html):
pattern = re.compile('.*?board-index.*?">(.*?)' #序号
+'.*?data-src="(.*?)"' #图片地址
+'.*?class="name">(.*?)' #影片名
+'.*?class="star">(.*?)' #主演
+'.*?class="releasetime">(.*?)'#上映时间
+'.*?class="score">(.*?)'#评分整数
+'.*?class="fraction">(.*?)'#评分小数
+'.*? ',re.S)
items = pattern.findall(html) #返回一个数组
content = []
for item in items:
content.append({
'index':item[0],
'image':item[1],
'title':item[2],
'actor':item[3],
'time':item[4],
'score':item[5]+item[6]
})
return content
def write_tofile(content):
'''
#存为json形式文本文件
# for item in content:
# with open('result.txt','a',encoding='utf-8') as f:
# f.write(json.dumps(item,ensure_ascii=False)+'\n')
'''
#存为csv文件
for item in content:
print(item)
with open('result.csv','a',encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow([item['index'],item['image'],item['title'],item['actor'],item['time'],item['score']])
f.close()
if __name__ == '__main__':
#写入csv文件 头部
with open('result.csv','w',encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['序号', '图片地址', '影片名', '主演', '上映时间', '评分'])
f.close()
for i in range(10):
url = 'https://maoyan.com/board/4?offset='+str(i*10)
print(url)
#发送请求 获取响应
html = get_one_page(url)
#解析响应内容
content = parse_one_page(html)
#数据存储
write_tofile(content)
#每个页面间隔1s
time.sleep(1)