美文网首页
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