BeautifulSoup4爬取猫眼电影前一百

最开始学习python,是因为爬虫。最初学习小甲鱼的教学视频,后来在小甲鱼的论坛上发现了用bs4爬取豆瓣前一百,当时怎么也看不懂。后来系统的学习了一下爬虫。参考了崔大佬的爬虫之后,改编书上的例子(书上用正则法则),我这里用bs4,后文会附上正则法则解析网页。

 

系统流程:

1.观察页面构造--知道要提取多少页,url构造方式等

2.编写函数解析每一页--得到每一页需要的数据

3.数据清洗和保存--按一定格式存储

4.循环2-3爬取所有的页面

 

用到的库:

from requests.exceptions import RequestException

from urllib.parse import urlencode

from bs4 import BeautifulSoup

import requests

import json

import re

import time

一般来说用requests.get得到网页信息时可能会报错,那么需要用try...except的模式,第一个导入就是用来提供except情况的。 我这里偷了个懒,用urlencode()来构造url。因为电影排行前一百嘛,观察网页发现每一页介绍10个电影,那么必然就是10页了。

 

观察页面:

在这个主题里,还是看图说话的好,毕竟是观察嘛。网速有点卡,待老夫慢慢展开,各位看官多多包容。

打开Chrome浏览器。输入网址http://maoyan.com/board/4,然后用你们勤劳的手指,戳中F12。如下图所示。

不管图中有啥美女,我们继续我们伟大的爬虫事业。我一定不能让这该死的开发者工具阻挡住我伟大的视野,网页往下翻页,看到下一页,轻轻的一点。如下。

哼,美女没有了,换成二次元了。这可如何是好?既然世界那么恶劣,我们来看看这让人又爱又恨的开发者工具?不不不,我们不能死的太年轻。看到抬头了吗?那么url变化了。对比一下,多了一个

?offset=10。这肯定是告诉我们当前页是第11-20那么页码的规律是不是出来啦。我相信这个肯定难不住各位人见人爱的柯南们。

接下来当然得观察观察传说中需要提取的数据。不然写爬虫干嘛。你想想,获得信息最快捷的方式当然是直接看喽。不对不对,逻辑有问题,应该是获得少量信息最快捷的方法是看,获得大量的数据最快捷的方法当然是爬虫爬下来,然后再去看。每页都是介绍电影,当然我们需要的信息肯定是固定在每一页的固定地方的。不然每一页都写一遍代码,前端的小帅哥会升(gun)职(chu)加(gong)薪(si)的。毕竟费力不讨好简直就是浪费青春。所以比如指着《天空之城》点击右键,然后检查,性感的图又如下啦。

咳咳,各位认真看图的肯定发现,我指着的不是天空之城,答对了。真是些聪明的小伙伴。为了实例清楚,我往下翻页了。指了个中间位置的。如图第一行<dd>...</dd>后面还有好多<dd>。中间有个被打开的<dd>是不是发现我们要的索引信息都在<dd>里面。

好了,接下来撸起袖子,咱们开干。。。注意是袖子,不是裤子。

 

代码:

打开网页:

刚刚我们是用我们大眼睛观察,现在得用程序打开网页。如下:

def open_url(url):
    try:
        headers ={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36'}
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        return None

简单介绍一下,猫眼必须加上header伪装成浏览器,不然会被禁掉。这个headers是怎么回事呢,你可以把它理解成通行证。发送请求给服务器之后,服务器总的验证一下你是啥玩意,所以就只能看看headers喽。当前大家都是互相相信的,至于我伪不伪造通行证,那必然的不然谁让你爬啊。

 

解析每一页:

当然是传入offset参数,然后用for循环调用函数,这样是不是我们也只用写一个解析一页的函数就好了。

def parse_page(html):
    soup = BeautifulSoup(html, 'lxml')
    items = soup.select('dd')
    for item in items:
        index = item.find(name='i', class_='board-index').get_text()
        name = item.find(name='p', class_='name').get_text()
        start = item.find(name='p', class_='star').get_text().strip()
        time = item.find(name='p', class_='releasetime').string
        score = item.find(name='p', class_='score').get_text()
        yield {
            'index':index,
            'name':name,
            'star':start,
            'time':time,
            'score':score
        }

细心的帅哥肯定发现了。我用的是find()函数,哈哈哈。一般都是用find_all(),是因为我长得帅所以标新立异吗?那当然不是。传说中的理由是,find返回的直接是网页标签,而find_all返回的是列表,列表里面包含标签。图省事。当然用find喽。

 

保存:

这里数据就不用怎么清洗了,毕竟我用字典形式返回来,以咱们普九的力度来说,大家都看得懂字典的内容的。当然你也可以不用字典,返回一个列表,但是,你的列表里面可能完全没有顺序。有些是电影名在最前面,有些可能是评分在最前面,看起来一点都不爽,所以用字典号啦。

def save(item):
    with open('maoyan.txt', 'a', encoding='utf-8') as f:
        f.write(json.dumps(item, ensure_ascii=False) + '\n')

 

if __name__ == '__main__':

登场的不用说了,这句话很霸气的告诉编译器,老子程序从这行下面开始执行。

if __name__ == '__main__':
    for i in range(10):
        base_url = 'http://maoyan.com/board/4?'
        params = {'offset': i*10}
        url = base_url + urlencode(params)
        html = open_url(url)
        for item in parse_page(html):
            print(item)
            save(item)
        time.sleep(2)

成果展示:

 

总结:

bs4真的很好用。。等等你说的正则呢。哈哈哈哈当然是下回分解喽。

其实现在我感觉解析网页用的比较多的就是Beautiful Soup 和pyquery。当然还有XPath。我觉得XPath规矩太多有点不符合我想的那样,所有我主要就是用pyquery,然后非常细节的就比如从一段话中提取一些信息,那么我用正则。正则表达式完全的解析一个网页其实很容易出错,而且前端小哥哥稍微改那么一丢丢,可能你的程序就game over了。

祝大家愉快,各位未来程序猿快睡啦。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值