# Python开发学习笔记:爬取猫眼电影排行
# 导入包:导入包如果没有使用颜色会保持为灰色
import json
import requests
# re模块:提供了对正则表达式的支持
import re
# 实现获取猫眼电影排行第一页的函数
def get_one_page(url):
# 设置请求头中的UA(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'
}
# 使用requests的get发起请求并获得响应结果
response = requests.get(url,headers=headers)
# 判断响应结果的状态码;200代表成功
if response.status_code == 200:
return response.text
return None
# 定义HTML页面内容解析函数
def parse_one_page(html):
# print("打印html内容")
# print(html)
print("开始解析文本内容")
# re.compile(pattern[,flags]):根据包含正则表达式的字符串创建模式对象,以提高匹配效率
# .*:匹配任意字符;?:匹配0个或1个前面的正则表达式定义的片段,非贪婪模式
# ():匹配括号内的表达式,也表示一个组
# 根据源码分析正则表达式:
# (1)匹配电影排行:<dd>.*?board-index.*?>(.*?)</i>
# (2)匹配电影图片:.*?data-src="(.*?)"
# (3)匹配电影名称:.*?name.*?a.*?>(.*?)</a>
# (4)匹配主演人员:.*?star.*?>(.*?)</p>
# (5)匹配上映时间:.*?releasetime.*?>(.*?)</p>
# (6)匹配电影评分:.*?integer.*?>(.*?)</i>.*?fraction.*?>(.*?)</i>.*?</dd>
pattern = re.compile('<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>'
'.*?star.*?>(.*?)</p>'
'.*?releasetime.*?>(.*?)</p>.*?integer.*?>(.*?)</i>.*?fraction.*?>(.*?)</i>.*?</dd>', re.S)
# 获取匹配结果
# re.findall(pattern,string):返回一个列表,其中包含字符串中所有与模式匹配的子串
items = re.findall(pattern, html)
# 遍历结果并生成字典
# str.strip():删除字符串开头和末尾的空白(不包括中间的空白)并返回结果
# item[3].strip()[3:]:利用切片截取字符串;[3:]代表从item[3]的第四位开始截取一直到末尾
# yield:生成器,包含yield的语句都是生成器
for item in items:
yield {
'index': item[0],
'image': item[1],
'title': item[2].strip(),
'actor': item[3].strip()[3:] if len(item[3]) > 3 else '',
'time': item[4].strip()[5:] if len(item[4]) > 5 else '',
'score': item[5].strip()+item[6].strip()
}
# 定义文本写入函数
# open(文件名,打开模式,编码):
# 打开模式:
# (1).'x':独占写入模式
# (2).'a':附加模式
# (3).'b':二进制模式(与其它模式结合使用)
# (4).'t':文本模式(默认值,与其它模式结合使用)
# (5).'+':读写模式(与其它模式结合使用)
# (6).'r':读取模式(默认值)
# (7).'w':写入模式
# with语句:打开文件并将其赋值给一个变量(如 f ),在语句体中将数据写入文件,到达语句末尾时将自动关闭文件
# 即便出现异常也是如此
# json.dumps:用于将 Python 对象编码成 JSON 字符串
# json.loads 用于解码 JSON 数据。该函数返回 Python 字段的数据类型。
def write_in_txt(content):
with open('result.txt', 'a', encoding='utf-8') as f:
print(type(json.dumps(content)))
f.write(json.dumps(content, ensure_ascii=False)+'\n')
# 定义主函数
def main(offset):
url = "https://maoyan.com/board/4"+str(offset)
html = get_one_page(url)
# 函数parse_one_page使用了生成器,生成器会返回多个结果
results = parse_one_page(html)
for result in results:
write_in_txt(result)
# 运行主函数
# __name__ == '__main__':用于判断当前文件是自己直接执行还是被其他文件当做模块调用执行:
# 如果是直接执行则为True,否则为False
if __name__ == '__main__':
for i in range(10):
main(offset=i*10)