抓取猫眼电影top100

一、目标

运用requests+正则表达式爬取猫眼电影top100的电影图片、名称、时间、评分等信息,提取站点的url"http://maoyan.com/board/4",提取结果以文本的形式保存下来。

二、准备工作

1. 安装python

首先,下载Python3,这里使用Python3.6.5版本,64位。

地址链接:https://www.python.org/downloads/

双击打开,进行安装。特别注意:要勾选上"Add to Path"选项,否则后面会很麻烦。

调出命令符窗口,输入"python",如果出现下图界面,就说明安装成功。

抓取猫眼电影top100  

2. 安装pycharm

PycharmPython IDE的一种,可以帮助用户提高效率,比如调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制。此外,该IDE提供了一些高级功能,以用于支持Django框架下的专业Web开发。

从网站下载pycharm,下载链接为:

 https://www.jetbrains.com/pycharm/download/#section=windows

3. 安装使用到的第三方库:

requests库:

request对象是从客户端向服务器发出请求,包括用户提交的信息以及客户端的一些信息。客户端可通过HTML表单或在网页地址后面提供参数的方法提交数据,然后通过request对象的相关方法来获取这些数据。request的各种方法主要用来处理客户端浏览器提交的请求中的各项参数和选项。

requests库可以直接pycharm下载(如下图)

抓取猫眼电影top100

在打开的setting界面中我们点击python的解释器,你会看到很多导入的第三方库,如下图所示,点击最右边的加号

抓取猫眼电影top100

在弹出的available packages界面中,你会看到一个搜索框,如下图所示

抓取猫眼电影top100

然后我们搜索一个插件,比如我搜索simplejson这个插件,会出现如下图所示的界面点击下载

抓取猫眼电影top100

三、抓取分析

我们要抓取的目标站点为http://maoyan.com/board/4,打开之后的磅单信息如图。

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

抓取猫眼电影top100

将页面滚动到最下方,可以发现有分页的列表,直接点击第二页,可以发现页面的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的电影。

 抓取猫眼电影top100

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

四、获取首页

1. 获取一个url下的html文件

def get_one_page(url):

headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36"
    
}
    try:                              #异常处理
        
respone = requests.get(url,headers=headers)
        if respone.status_code == 200:
            return respone.text #请求成功
        
return None
    except
RequestException:
        return None
def
main(offset):#主函数运行
    
url = "http://maoyan.com/board/4?offset="+str(offset)
    html = get_one_page(url)
    print(html)
if __name__ == '__main__':
    main(1)

 2. 抓取的结果如下(只截取部分)

 抓取猫眼电影top100

 抓取猫眼电影top100

可以看到现在抓取的内容是很混乱的我们很难找到有用的信息所以我们要用正则表达式进行网页的解析

 五、正则提取

1. 用正则表达式解析网页

def parse_one_page(html):       
    
pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
    
+'.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'
    
+'.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',re.S)
    items = re.findall(pattern,html)
    print(items)
    for item in items:  #构造生成器
        
yield{
            'index':item[0],
            'image':item[1],
            'title':item[2],
            'actor':item[3].strip()[3:],
            'time':item[4].strip()[5:],
            'score':item[5]+item[6]
        }

2. 结果如下(只截取部分结果)

 抓取猫眼电影top100

六、写入文件

我们将取的结果写入文件,这里直接写入到一个文本文件,这里通过json库的dumps()方法实现字典的序列化,并指定ensure_ascii的参数为Flase,这样保证输出结果是中文形式而是不Unicode编码,代码如下:

 def write_to_file(content):    

    with open('result.txt','a',encoding='utf-8') as f:
        f.write(json.dumps(content,ensure_ascii=False)+'\n')
        f.close()

七、抓取一页内容

我们进入到猫眼top100可以看到里面有很多页数,观察他们的url,可以发现只是最后面不同而已,所以我们可以使用多线程抓取,提高抓取效率 

if __name__ == '__main__':

  #for i in range(10):      #抓取一页
       # main(i*10)
     
pool = Pool()#提高抓取效率
     
pool.map(main,[i*10 for i in range(10)])

八、整合代码

1. 源代码

import requests
import re
import json
from multiprocessing import Pool
from requests.exceptions import RequestException
def get_one_page(url):#获取一个url下的html文件
    
headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36"
    
}
    try:                              #异常处理
        
respone = requests.get(url,headers=headers)
        if respone.status_code == 200:
            return respone.text #请求成功
        
return None
    except RequestException:
        return None
def parse_one_page(html):       #用正则表达式解析网页
    
pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'
    
+'.*?>(.*?)</ a>.*?star">(.*?)</p >.*?releasetime">(.*?)</p >'
    
+'.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',re.S)
    items = re.findall(pattern,html)
    print(items)
    for item in items:  #构造生成器
        
yield{
            'index':item[0],
            'image':item[1],
            'title':item[2],
            'actor':item[3].strip()[3:],
            'time':item[4].strip()[5:],
            'score':item[5]+item[6]

        }
def write_to_file(content):#将爬取的内容写入文件
    
with open('result.txt','a',encoding='utf-8') as f:
        f.write(json.dumps(content,ensure_ascii=False)+'\n')
        f.close()
def main(offset):#主函数运行
    
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)
    
pool = Pool()#提高抓取效率
    
pool.map(main,[i*10 for i in range(10)])

2. 爬取结果

抓取猫眼电影top100