Python爬虫项目--爬取猫眼电影Top100榜(完整源码)!

本次抓取猫眼电影Top100榜所用到的知识点:

  1. python requests库

  2. 正则表达式

  3. csv模块

  4. 多进程

正文

目标站点分析

通过对目标站点的分析, 来确定网页结构, 进一步确定具体的抓取方式.

1. 浏览器打开猫眼电影首页, 点击"榜单", 点击"Top100榜", 即可看到目标页面.

  1. 浏览网页, 滚动到下方发现有分页, 切换到第2页, 发现: URL从 http://maoyan.com/board/4变换到http://maoyan.com/board/4?offset=10, 多次切换页码offset都有改变, 可以确定的是通过改变URL的offset参数来生成分页列表.

项目流程框架:

获取单页源码

#抓取猫眼电影TOP100榜
import requests
import time
from requests.exceptions import RequestException
def get_one_page():
    '''获取单页源码'''
    try:
        url = "http://maoyan.com/board/4?offset={0}".format(0)
        headers = {
            "User-Agent":"Mozilla/5.0(WindowsNT6.3;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/68.0.3440.106Safari/537.36"
        }
        res = requests.get(url, headers=headers)
        # 判断响应是否成功,若成功打印响应内容,否则返回None
        if res.status_code == 200:
            print(res.text)
        return None
    except RequestException:
        return None
def main():
    get_one_page()
if __name__ == '__main__':
    main()
    time.sleep(1)

执行即可得到网页源码, 那么下一步就是解析源码了

解析单页源码

导入正则表达式re模块, 对代码进行解析, 得到想要的信息.

import re

def parse_one_page(html):
    '''解析单页源码'''
    pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?name"><a.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime'
                         + '.*?>(.*?)</p>.*?score.*?integer">(.*?)</i>.*?>(.*?)</i>.*?</dd>',re.S)
    items = re.findall(pattern,html)
    print(items)
    #采用遍历的方式提取信息
    for item in  items:
        yield {
            'rank' :item[0],
            'title':item[1],
            'actor':item[2].strip()[3:] if len(item[2])>3 else '',  #判断是否大于3个字符
            'time' :item[3].strip()[5:] if len(item[3])>5 else '',
            'score':item[4] + item[5]
        }
def main():
    html = get_one_page()
    for item in parse_one_page(html):
        print(item)

if __name__ == '__main__':
    main()
    time.sleep(1)

提取出信息之后, 那么下一步就是保存到文件

保存到文件中

这里采用两种方式, 一种是保存到text文件, 另一种是保存到csv文件中, 根据需要选择其一即可.

  1. 保存到text文件
import json

def write_to_textfile(content):
    '''写入到text文件中'''
    with open("MovieResult.text",'a',encoding='utf-8') as f:
        #利用json.dumps()方法将字典序列化,并将ensure_ascii参数设置为False,保证结果是中文而不是Unicode码.
        f.write(json.dumps(content,ensure_ascii=False) + "\n")
        f.close()
def main():
    html = get_one_page()
    for item in parse_one_page(html):
        write_to_textfile(item)

if __name__ == '__main__':
    main()
    time.sleep(1)
  1. 保存到CSV文件

其文件以纯文本的形式存储表格数据

import csv
def write_to_csvfile(content):
    '''写入到csv文件中'''
    with open("MovieResult.csv",'a',encoding='gb18030',newline='') as f:
        # 将字段名传入列表
        fieldnames = ["rank", "title", "actor", "time", "score"]
        #将字段名传给Dictwriter来初始化一个字典写入对象
        writer = csv.DictWriter(f,fieldnames=fieldnames)
        #调用writeheader方法写入字段名
        writer.writeheader()
        writer.writerows(content)
        f.close()
def main():
    html = get_one_page()
    rows = []
    for item in parse_one_page(html):
        #write_to_textfile(item)
        rows.append(item)
    write_to_csvfile(rows)
if __name__ == '__main__':
    main()
    time.sleep(1)

单页的信息已经提取出, 接着就是提取多个页面的信息

获取多个页面

  1. 普通方法抓取
def main(offset):
    url = "http://maoyan.com/board/4?offset={0}".format(offset)
    html = get_one_page(url)
    rows = []
    for item in parse_one_page(html):
        #write_to_textfile(item)
        rows.append(item)
    write_to_csvfile(rows)
if __name__ == '__main__':
    #通过遍历写入TOP100信息
    for i in range(10):
        main(offset=i * 10)
        time.sleep(1)
  1. 多进程抓取
from multiprocessing import Pool

if __name__ == '__main__':
    # 将字段名传入列表
    fieldnames = ["rank", "title", "actor", "time", "score"]
    write_to_csvField(fieldnames)
    pool = Pool()
    #map方法会把每个元素当做函数的参数,创建一个个进程,在进程池中运行.
    pool.map(main,[i*10 for i in range(10)])

完整代码

#抓取猫眼电影TOP100榜
from multiprocessing import Pool
from requests.exceptions import RequestException
import requests
import json
import time
import csv
import re
def get_one_page(url):
    '''获取单页源码'''
    try:
        headers = {
            "User-Agent":"Mozilla/5.0(WindowsNT6.3;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/68.0.3440.106Safari/537.36"
        }
        res = requests.get(url, headers=headers)
        # 判断响应是否成功,若成功打印响应内容,否则返回None
        if res.status_code == 200:
            return res.text
        return None
    except RequestException:
        return None
def parse_one_page(html):
    '''解析单页源码'''
    pattern = re.compile('<dd>.*?board-index.*?>(\d+)</i>.*?name"><a.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime'
                         + '.*?>(.*?)</p>.*?score.*?integer">(.*?)</i>.*?>(.*?)</i>.*?</dd>',re.S)
    items = re.findall(pattern,html)
    #采用遍历的方式提取信息
    for item in  items:
        yield {
            'rank' :item[0],
            'title':item[1],
            'actor':item[2].strip()[3:] if len(item[2])>3 else '',  #判断是否大于3个字符
            'time' :item[3].strip()[5:] if len(item[3])>5 else '',
            'score':item[4] + item[5]
        }

def write_to_textfile(content):
    '''写入text文件'''
    with open("MovieResult.text",'a',encoding='utf-8') as f:
        #利用json.dumps()方法将字典序列化,并将ensure_ascii参数设置为False,保证结果是中文而不是Unicode码.
        f.write(json.dumps(content,ensure_ascii=False) + "\n")
        f.close()

def write_to_csvField(fieldnames):
    '''写入csv文件字段'''
    with open("MovieResult.csv", 'a', encoding='gb18030', newline='') as f:
        #将字段名传给Dictwriter来初始化一个字典写入对象
        writer = csv.DictWriter(f,fieldnames=fieldnames)
        #调用writeheader方法写入字段名
        writer.writeheader()
def write_to_csvRows(content,fieldnames):
    '''写入csv文件内容'''
    with open("MovieResult.csv",'a',encoding='gb18030',newline='') as f:
        #将字段名传给Dictwriter来初始化一个字典写入对象
        writer = csv.DictWriter(f,fieldnames=fieldnames)
        #调用writeheader方法写入字段名
        #writer.writeheader()            ###这里写入字段的话会造成在抓取多个时重复.
        writer.writerows(content)
        f.close()

def main(offset):
    fieldnames = ["rank", "title", "actor", "time", "score"]
    url = "http://maoyan.com/board/4?offset={0}".format(offset)
    html = get_one_page(url)
    rows = []
    for item in parse_one_page(html):
        #write_to_textfile(item)
        rows.append(item)
    write_to_csvRows(rows,fieldnames)

if __name__ == '__main__':
    # 将字段名传入列表
    fieldnames = ["rank", "title", "actor", "time", "score"]
    write_to_csvField(fieldnames)
    # #通过遍历写入TOP100信息
    # for i in range(10):
    #     main(offset=i * 10,fieldnames=fieldnames)
    #     time.sleep(1)
    pool = Pool()
    #map方法会把每个元素当做函数的参数,创建一个个进程,在进程池中运行.
    pool.map(main,[i*10 for i in range(10)])

效果展示:

最终采用写入csv文件的方式.

关于Python技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!

点击领取,100%免费!

👉Python所有方向的学习路线👈

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。(全套教程文末领取)

在这里插入图片描述

👉Python学习视频600合集👈

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

在这里插入图片描述

温馨提示:篇幅有限,已打包文件夹,获取方式在:文末
👉Python70个实战练手案例&源码👈

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

在这里插入图片描述

👉Python大厂面试资料👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

👉Python副业兼职路线&方法👈

学好 Python 不论是就业还是做副业赚钱都不错,但要学会兼职接单还是要有一个学习规划。

在这里插入图片描述

👉 这份完整版的Python全套学习资料已经上传,朋友们如果需要可以扫描下方CSDN官方认证二维码或者点击链接免费领取保证100%免费

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值