美文网首页
1.requests+正则表达式爬取猫眼电影排行

1.requests+正则表达式爬取猫眼电影排行

作者: yhxt | 来源:发表于2018-03-23 15:49 被阅读0次

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)])

效果图

相关文章

网友评论

      本文标题:1.requests+正则表达式爬取猫眼电影排行

      本文链接:https://www.haomeiwen.com/subject/arjxcftx.html