python网络爬虫实例:Requests+正则表达式爬取猫眼电影TOP100榜

标签: 网络爬虫  python  requests库  re正则表达式

一、前言

最近在看崔庆才先生编写的《Python3网络爬虫开发实战》这本书,学习了requests库和正则表达式,爬取猫眼电影top100榜单是这本书的第一个实例,主要目的是要掌握requests库和正则表达式在实际案例中的使用。

二、开发环境

运行平台: Windows 10
Python版本: Python3.6
IDE: PyCharm

三、爬取思路

  1. 抓取单页内容
  2. 正则表达式提取有用信息
  3. 保存信息
  4. 下载TOP100所有电影信息
  5. 多线程抓取

爬取单页内容

首先打开Chrome浏览器,打开猫眼电影网站(http://maoyan.com/)然后点击榜单,点击TOP100榜。
这里写图片描述
然后通过requests库将整个HTML代码获取下来:

import requests
from requests.exceptions import RequestException #捕捉异常

def get_one_page(url):
    '''
    获取网页html内容并返回
    '''
    try:
        # 获取网页html内容
        response = requests.get(url)
        # 通过状态码判断是否获取成功
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        return None

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

if __name__ == '__main__':
    main()

正则表达式提取有用信息

然后按F12,查看网页的源代码,然后逐层找到要爬取信息的所在位置①排名、②电影封面、③电影名称、④主演、⑤上映时间、⑥评分(整数和小数两部分)
这里写图片描述
利用正则表达式解析提取出来:

import re

def parse_one_page(html):
    '''
    解析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)

    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]
        }

# 修改main()函数
def main():
    url = 'http://maoyan.com/board/4'
    html = get_one_page(url)
    for item in parse_one_page(html):
        print(item)

保存信息

将爬取的信息保存成文件形式,方便以后查看

def write_to_file(content):               #存储到文件中
    with open('result.txt','a',encoding='utf-8') as f:
        f.write(json.dumps(content,ensure_ascii=False)+'\n') #利用json.dumps将字典转换成字符串的形式
        f.close()

下载TOP100所有电影信息

通过点击下面的页面标签换页发现URL中多了offset参数,每次换页更改的都是offset参数后面的数字,数字更改的规律都是 (页码数-1)*10
这里写图片描述

所以只需要更改main函数动态改变URL即可完成:

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 rang(10):
        main(i * 10)

多线程爬取

此次爬取的数据不太多,引入多线程是为了以后爬取更多的数据做准备的,多线程爬取数据能让爬取的速度更加的迅速,节省爬取时间

from multiprocessing import Pool

if __name__ == '__main__':
    pool=Pool()
    pool.map(main,[i*10 for i in range(10)])

四、完整代码

#导入需要使用的模块
import requests
from multiprocessing import Pool
from requests.exceptions import RequestException
import re
import json

#尝试连接获取页面
def get_one_page(url):
    try:
        response=requests.get(url)
        if response.status_code==200:
            return response.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)
    for item in items:
        yield {
            'index':item[0],
            'image':item[1],
            'title':item[2],
            'ator':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') #利用json.dumps将字典转换成字符串的形式
        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__':
    pool=Pool()
    pool.map(main,[i*10 for i in range(10)])

五、总结

熟练使用requests库和正则表达式是网络爬虫的基础,大多数的网站都可以利用requests库+正则表达式将需要信息爬取下来

需要代码的可以去我的github上面fork,给个star也行!
GitHub:https://github.com/ldz0/python-Requests-Re-maoyanTOP100

原文链接:加载失败,请重新获取