Requests+正则表达式爬取猫眼电影

目标

提取出猫眼电影TOP100的电影名称、时间、评分、图片等信息,提取站点的URL为http://maoyan.com/board/4,提取的结果以文本的形式保存下来。

准备工作

请安装好requests库

pip install requests

 requests库的基本用法可参数这篇文章:http://www.cnblogs.com/0bug/p/8899841.html

抓取分析

我们需要抓取的目标站点为http://maoyan.com/board/4 打开之后便可以看到榜单信息,如图所示。

排名第一的电影是霸王别姬,页面中显示的有效信息有影片名称、主演、上映时间、上映地区、评分、图片等信息。

将页面滚动到最下方,可以发现有分页的列表,直接点击第二页,观察页面的URL内容发生了怎样的变化,如图所示。

可以发现页面的URL变成http://maoyan.com/board/4?offset=10,比之前的URL多了一个参数,那就是offset=10,而且目前的排行结果是排行11~20名的电影,初步推断这是一个偏移量的参数,再点击下一页,发现页面的URL变成了http://maoyan.com/board/4?offset=20,参数offset变成了20,而且显示的结果是排行21~30的电影。

由此可以总结出规律,offset代表偏移量,如果偏移量为n,则显示电影序号就是n+1到n+10,每页显示10个,所以,如果想获取TOP100电影,只需要分开请求10次,而10次的offset参数分别设置为0、10、20......90即可,这样获取不同的页面之后,再用正则表达式提取出相关信息,就可以得到TOP100的所有电影信息了。

流程框架:

扫描二维码关注公众号,回复: 40951 查看本文章

获取首页

import requests


def get_one_page(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
        return response.text
    return None


def main():
    url = 'http://maoyan.com/board/4'
    html = get_one_page(url)
    print(html)


main()

正则提取

回到页面,在开发者模式下的Network监听组建中查看源代码。

注意,这里不用在Elements选项卡中直接查看源代码,因为那里的源码可能经过JavaScript操作而与原始请求不同。

其中看到一个条木的源码如下:

可以看到,一部电影信息对应的源码是一个dd节点,我们用正则表达式提取出这里面的一些电影信息。

1.排名

排名信息在class为board-index的i节点内,这里利用非贪婪匹配来提取i节点内的信息,正则表达式写为:

<dd>.*?board-index.*?>(.*?)</i>

2.电影的图片

接下来,可以看到a节点内部有两个img节点,经过检查后发现,第二个img节点的data-src属性是图片链接,正则表达式改写为:

<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)"

3.电影名称

再往后,提取电影名,它后面的p节点内,class为name,所以可以用name来做一个标志位,然后进一步提取到期内a节点的正文内容:

<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>

4.再提取主演、时间、评分等内容,都是同样的原理,最后正则表达式写为:

<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>.*?star.*?>(.*?)</p>.*?releasetime.*?>(.*?)</p>.*?integer.*?>(.*?)</i>.*?fraction.*?>(.*?)</i>.*?</dd>

<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>.*?star.*?>(.*?)</p>.*?releasetime.*?>(.*?)</p>.*?integer.*?>(.*?)</i>.*?fraction.*?>(.*?)</i>.*?</dd>

这样一个正则表达式可以匹配一个电影的结果,里面匹配了7个嘻嘻你,接下来调用findall()方法提取所有的内容

import re
def parse_one_page(html):
    pattern = re.compile(
        '<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)".*?name.*?a.*?>(.*?)</a>.*?star.*?>(.*?)</p>.*?releasetime.*?>(.*?)</p>.*?integer.*?>(.*?)</i>.*?fraction.*?>(.*?)</i>.*?</dd>',
        re.S)
    item = re.findall(pattern, html)
    print(item)

  

猜你喜欢

转载自www.cnblogs.com/0bug/p/8906490.html