使用Requests库+re库爬取猫眼电影评分

使用Requests库+re库爬取猫眼电影评分

作者:小胖

0x1: 分析

  1. 在简单的翻页中,我们可以知道.网页涵盖了以下几个规律
    1.offset参数的值是除以30就是当前的页面
    2.每个页面只有30个电影信息

  2. 打开谷歌开发者调试工具.抓包寻找突破点.

     此处假设当前页面 = page
     1.url:https://maoyan.com/films?showType=3&offset=str(page*30)
     2.页面结构是有规律的。因此可以编写正则表达式来匹配
               data-val="{movieId:(.*?)}">(.*?)</a>.*?integer">(.*?)<.*?fraction">(.*?)</i>
    

我认为的突破点就如同上面2点,除了上面2点就没啥难点了.于是乎,让我们开始敲代码吧

0x2: Python代码编写

A:构造一个Crawl类,同时编写一个__init__方法。我在init方法中初始化了我们需要一次需要爬取多少页的参数page,以及构造了我们的URL列表 URLS

class crawl():
    def __init__(self,page):
        self.header = {
            "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
            "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3"
        }
        self.URLS = ["https://maoyan.com/films?showType=3&offset=%s"% ((i+1)*30) for i in range (page)]

B:当我们拥有了URL列表以后,我们应该要有一个访问页面的功能,于是乎,我们的Requests库就需要使用到了。同时编写一个request方法

def request(self,url):
    try:

        resp = requests.get(url,headers = self.header)
        print(resp.status_code)
        if resp.status_code == 200:
            return resp.content.decode('utf-8')
        return None
    except RequestException:
        return None

C:当我们访问完一个页面,我要就需要思考,如何才能把数据提取出来,这个时候我们就使用到了正则表达式(Regular expression)。编写一个parse_page方法。

    def parse_page(self,html):
    # 这边的正则表达式还有待优化
        pattern = re.compile(r'data-val="{movieId:(.*?)}">(.*?)</a>.*?integer">(.*?)<.*?fraction">(.*?)</i>',re.S)
        items = re.findall(pattern,html)
        for item in items:
            yield{
                'id':item[0],
                'title':item[1],
                'score':item[2] + item[3]
            }

D:可是东西可以抓取下来,然后我们的数据要如何保存下来呢? 所以我们写一个write_to_file方法。这里用了json库,在dumps方法我选择了ensure_ascii=False是因为我想输出的内容是中文的,而不是ascii编码的内容。大家可以试试有ensure_ascii和没有ensure_ascii写出来的文件有何不同。

    def write_to_file(self,context):
        with open('info.txt','a') as f:
            f.write(json.dumps(context,ensure_ascii=False) + '\n')

E:这时候我们就可以在测试下,写个main方法,把这几个方法配合的调用起来。

def main(self):

    for url in self.URLS:
        html = self.request(url)
        if html == None:
            return None
        for item in self.parse_page(html):
            print(item)
            self.write_to_file(item)

至此,我们的代码就全部编写完毕了。

0x3 : 代码运行

{'id': '343034', 'title': '速度与激情9', 'score': '6.6'}
{'id': '1262590', 'title': '女王的柯基', 'score': '8.6'}
{'id': '344264', 'title': '战狼2', 'score': '9.7'}
{'id': '1229683', 'title': '铤而走险', 'score': '8.4'}
{'id': '1212492', 'title': '老师·好', 'score': '9.3'}
{'id': '247730', 'title': '终结者:黑暗命运', 'score': '8.8'}
{'id': '248906', 'title': '流浪地球', 'score': '9.2'}
{'id': '1205290', 'title': '检察方的罪人', 'score': '8.4'}
{'id': '1198925', 'title': '蜘蛛侠:英雄远征', 'score': '9.0'}
{'id': '902819', 'title': '死寂逃亡', 'score': '6.2'}
{'id': '894477', 'title': '宝莱坞机器人2.0:重生归来', 'score': '7.1'}
{'id': '1281095', 'title': '紫罗兰永恒花园外传:永远与自动手记人偶', 'score': '8.7'}
{'id': '341578', 'title': '那些女人', 'score': '8.5'}
{'id': '346119', 'title': '死亡通知单之暗黑者', 'score': '7.2'}
{'id': '1290250', 'title': '2019年国际篮联篮球世界杯', 'score': '7.8'}
{'id': '1196202', 'title': '天使陷落', 'score': '8.5'}
{'id': '1294987', 'title': '奉天往事', 'score': '9.3'}
{'id': '670240', 'title': '魔女', 'score': '7.1'}
{'id': '257594', 'title': '小丑回魂', 'score': '7.6'}

0x4 : 总结

猫眼电影总体来说是没有什么难度的,写这篇文章就是为了回顾下Python requests和re库的使用.太久没动Python了。对于新入门的同学,建议可以寻找这类网站来练手,无反爬,至少我目前没遇到。其次需要注意一下猫眼访问页面的时候,headers。如果没有USERAGENT会被BAN掉。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值