requests+正则表达式爬取猫眼电影排行
具体用法说明详见代码注释:
运行代码结果会在当前文件所在目录生成一个result.txt的文件
注意:为了让读者看的更清晰,我已将正则表达式和匹配内容一一对应起来
1.单页爬取
import re
import json
import requests
from requests.exceptions import RequestException
def get_one_page(url):
'''1.爬取网页html文件'''
try:
# 作者发现猫眼电影现在对爬虫做了封锁,必须添加下面的headers才行,不然会被封禁
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'}
response = requests.get(url,headers=headers)
if response.status_code == 200:
return response.text
return None
except RequestException:
return None
def parse_one_page(html):
'''2.通过正则表达式对爬取的html文件进行清洗(匹配)'''
# 正则表达式匹配排名:<dd>.*?board-index.*?>(\d+)</i>
# 封面图:.*?data-src="(.*?)"
# 电影名称:.*?name"><a.*?>(.*?)</a>
# 主演:.*?star">(.*?)</p>
# 上映时间:.*?releasetime">(.*?)</p>
# 评分左半部分:.*?integer">(.*?)</i>
# 评分右半部分:.*?fraction">(.*?)</i>
pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>'+
'.*?data-src="(.*?)"'+
'.*?name"><a.*?>(.*?)</a>'+
'.*?star">(.*?)</p>'+
'.*?releasetime">(.*?)</p>'+
'.*?integer">(.*?)</i>'+
'.*?fraction">(.*?)</i>', re.S)
items = re.findall(pattern,html)
# 对爬取数据进行整理
for item in items:
# print(item)
# print('index:'+item[0]),
# print('image:'+item[1]),
# print('title:'+item[2]),
# print('actor:'+item[3].strip()[3:]),
# print('time:'+item[4][5:]),
# print('scorce:'+item[5]+item[6]),
yield {
'排名':item[0],
'封面':item[1],
'电影名称':item[2],
'主演':item[3].strip()[3:],
'上映时间':item[4][5:],
'评分':item[5]+item[6]
}
def write_to_file(content):
with open('result.txt','a',encoding='utf-8') as f:
# content是字典形式,需要通过json.dumps()将其转换成字符串,并加上换行符
f.write(json.dumps(content,ensure_ascii=False)+'\n')
f.close()
def main():
'''3.主函数'''
url = 'http://maoyan.com/board/4'
html = get_one_page(url)
# 对爬取的结果进行遍历
for item in parse_one_page(html):
# print(item)
write_to_file(item)
if __name__ == '__main__':
main()
2.多页爬取
多页爬取只要根据网页特点,拼接处页面信息即可
观察每页的url:
首页:http://maoyan.com/board/4?
第一页:http://maoyan.com/board/4?offset=0
第二页:http://maoyan.com/board/4?offset=10
第三页:http://maoyan.com/board/4?offset=20
....
由此可见,页面每页就是设置个offset的参数即可,下面根据这个规律去修改我们的main()函数里面的url,其他不变
def main(offset):
'''3.主函数'''
url = 'http://maoyan.com/board/4?offset=' + str(offset)
html = get_one_page(url)
# 对爬取的结果进行遍历
for item in parse_one_page(html):
print(item)
write_to_file(item)
if __name__ == '__main__':
for i in range(10):
main(i*10)
3.多进程的爬取
首先引入进程池:from multiprocessing import Pool
然后对if__main__=='__main__'
进行修改即可
if __name__ == '__main__':
pool = Pool()
pool.map(main,[i*10 for i in range(10)])
完整代码:
import re
import json
from multiprocessing import Pool
import requests
from requests.exceptions import RequestException
def get_one_page(url):
'''1.爬取网页html文件'''
try:
# 作者发现猫眼电影现在对爬虫做了封锁,必须添加下面的headers才行,不然会被封禁
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'}
response = requests.get(url,headers=headers)
if response.status_code == 200:
return response.text
return None
except RequestException:
return None
def parse_one_page(html):
'''2.通过正则表达式对爬取的html文件进行清洗(匹配)'''
# 正则表达式匹配排名:<dd>.*?board-index.*?>(\d+)</i>
# 封面图:.*?data-src="(.*?)"
# 电影名称:.*?name"><a.*?>(.*?)</a>
# 主演:.*?star">(.*?)</p>
# 上映时间:.*?releasetime">(.*?)</p>
# 评分左半部分:.*?integer">(.*?)</i>
# 评分右半部分:.*?fraction">(.*?)</i>
pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>'+
'.*?data-src="(.*?)"'+
'.*?name"><a.*?>(.*?)</a>'+
'.*?star">(.*?)</p>'+
'.*?releasetime">(.*?)</p>'+
'.*?integer">(.*?)</i>'+
'.*?fraction">(.*?)</i>', re.S)
items = re.findall(pattern,html)
# 对爬取数据进行整理
for item in items:
# print(item)
# print('index:'+item[0]),
# print('image:'+item[1]),
# print('title:'+item[2]),
# print('actor:'+item[3].strip()[3:]),
# print('time:'+item[4][5:]),
# print('scorce:'+item[5]+item[6]),
yield {
'排名':item[0],
'封面':item[1],
'电影名称':item[2],
'主演':item[3].strip()[3:],
'上映时间':item[4][5:],
'评分':item[5]+item[6]
}
def write_to_file(content):
with open('result.txt','a',encoding='utf-8') as f:
# content是字典形式,需要通过json.dumps()将其转换成字符串,并加上换行符
f.write(json.dumps(content,ensure_ascii=False)+'\n')
f.close()
def main(offset):
'''3.主函数'''
url = 'http://maoyan.com/board/4?offset=' + str(offset)
html = get_one_page(url)
# 对爬取的结果进行遍历
for item in parse_one_page(html):
print(item)
write_to_file(item)
if __name__ == '__main__':
pool = Pool()
pool.map(main,[i*10 for i in range(10)])