目标
提取出猫眼电影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的所有电影信息了。
流程框架:
获取首页
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)