Logo

郎哥编程

爬取matplotlib案例源代码

2020-12-20 257

matplotlib是图形绘制库,使用matplotlib可以方便的绘制函数图形、以及直方图、条形图、散点图等统计图形,主要用于科学计算和数据分析等领域。在matplotlib官网提供了很多案例源代码,每个案例的源代码需要单独下载。若希望快速下载全部案例源代码,可以编写一个爬虫程序来下载全部的案例源代码。

下面使用PyCharm来建立matplotlib案例源代码爬虫项目。

1、 使用PyCharm建立爬虫项目

使用PyCharm建立matplotlib爬虫项目的步骤如下:

1、建立Pure Python项目,解释器选择Exsiting interpreter,即本地安装的Python解释器,如下图所示:

31.png

(2)展开PyCharm终端窗口(Terminal),在终端窗口使用Scrapy创建项目命令,创建爬虫项目,在终端窗口输入下面的Scrapy命令并回车执行命令:

scrapy startproject matplotlib

命令执行成功后,Scrapy会在matplotlib项目目录下创建Scrapy爬虫项目,爬虫项目名称为matplotlib,如下图所示:

32.png

创建的项目资源如下图所示:

33.png

(3)在终端窗口将当前工作目录切换到Scrapy项目目录下,如下图所示:

34.png

输入创建爬虫命令:

scrapy genspider spider_matplotlib www.matplotlib.org

命令执行成功后,Scrapy会在项目的spiders目录创建爬虫spider_matplotlib.py模块文件。如下图所示:

35.png

2、 分析matplotlib网站

项目要下载matplotlib网站的案例源代码,就需要了解matplotlib网站结构,找到案例源代码网页,然后对案例源代码网页进一步分析,编写XPath表达式提取案例源代码的下载链接。

通过对matplotlib网站观察分析得知,matplotlib网站的所有案例网页链接都在Examples网页内,网页地址如下:

https://www.matplotlib.org/gallery/index.html

观察index.html网页源代码,发现所有案例网页链接标签<a>的href属性值都包含子串“-py”,利用子串“-py”可以把所有案例网页链接提取出来,并能过滤掉不需要的链接。

某<a>标签代码如下:

<a 
class="reference internal" 
href="images_contours_and_fields/image_nonuniform.html#sphx-glr-gallery-images-contours-and-fields-image-nonuniform-py">
<span class="std std-ref">
Image Nonuniform
</span>
</a>

提取网页内全部<a>标签的href属性值的XPath表达式如下:

//a[contains(@href,'-py')]/@href

检测XPath表达式的正确性

可以使用Scrapy shell命令检测XPath表达式的正确性,在PyCharm的终端窗口输入下面的命令(如下图所示):

scrapy shell https://www.matplotlib.org/gallery/index.html

命令执行后,shell会爬取指定的url网页,并返回response实例对象。对象变量名称为response,开发者可以使用response来执行内容提取测试任务。

36.png

在PyCharm终端窗口shell环境下,输入下面的命令验证XPath表达式的正确性:

response.xpath("//a[contains(@href,'-py')]/@href").extract()

命令执行后,在PyCharm终端窗口会列出提取的网页案例URL,若提取内容不符合要求,需要进一步分析网页结构,修改XPath表达式。

分析下载页面

接下来分析下载页面,单击index.html网页的案例代码连接即可进入案例代码下载网页,观察下载网页源代码,文件下载链接代码如下(已简化):

<a class="reference download internal" download="" href="../../_downloads/79cca01aa25ff65b23b051f7e4ca55f5/linestyles.py"></a>

编写下面的XPath表达式即可提取文件下载URL:

//a[@class='reference download internal']/@href

3、 定义Item数据容器

项目目标主要是下载matplotlib网站的源代码,不需要存储爬取的数据。因此只需要在Item类定义下载文件必须的数据项即可。

在PyCharm编辑items.py文件,定义file_urls和files数据项。编辑代码如下:

import scrapy
class MatplotlibItem(scrapy.Item):
    # 案例分类
    catalog = scrapy.Field()
    # 定义file_urls数据项,存储源代码文件URL路径
    file_urls = scrapy.Field()
    # 定义files数据项,存储源代码下载路径
    files = scrapy.Field()

4、 定义文件下载管道类

Scrapy专门提供了一个用于下载文件的管道类FilesPipeline类,该管道类提供了file_path()、get_media_requests()、item_completed()三个重写方法,可以设置源代码文件存储路径、过滤准备要下载的源代码文件URL、对下载完成的源代码文件进一步处理。三个重写方法的使用参见《4..1. 下载网页图片》一节。

在爬虫matplotlib包目录下,编辑pipelines.py文件,代码如下:

# 导入os模块
import os
# 导入scrapy
import scrapy
# 导入适配器
from itemadapter import ItemAdapter
# 导入urlparse模块
from urllib.parse import urlparse
# 导入ImagesPipeline模块
from scrapy.pipelines.files import FilesPipeline
# 导入Scrapy异常处理模块
from scrapy.exceptions import DropItem
 
 
class MatplotlibPipeline(FilesPipeline):
 
    # 设置源代码文件存储路径
    def file_path(self, request, response=None, info=None):
        # 从request对象的meta字典获取Item数据项
        item = request.meta.get('item')
        # 获取catalog数据项,该数据项存储了案例类别
        catalog = item['catalog']
        filename = os.path.basename(urlparse(request.url).path)
        return '%s/%s' % (catalog,filename)
 
    # 设置需要下载的图片URL,并返回图片request
    def get_media_requests(self, item, info):
        # 遍历file_urls数据项,为每个图片URL生成request请求
        for file_url in item['file_urls']:
            # 设置meta字典,传递Item数据项
            yield scrapy.Request(file_url,meta={'item': item})
 
    # 存储图片下载路径
    def item_completed(self, results, item, info):
        # result是一个包含元组的列表
        # 元组包含两个值,第一个代表状态True/False,
        # 第二个值是一个dict对象,若元素中状态为True则取dict中的path值
        file_paths = [x['path'] for ok, x in results if ok]
        # 若image_paths为空,说明下载失败
        # 抛出DropItem异常
        if not file_paths:
            raise DropItem("文件下载失败")
        # 获取Item的适配器
        adapter = ItemAdapter(item)
        # 存储image_paths
        adapter['files'] = file_paths
        return item

5、 修改配置文件

修改配置文件,添加管道类配置项和文件存储路径配置项。

(1)添加管道类配置项

ITEM_PIPELINES = {
  'matplotlib.pipelines.MatplotlibPipeline': 300,
}

在配置文件中该配置项已经存在,只需要把语句前面的注释符去掉就可以。

(2)添加文件存储路径配置项

爬虫需要从配置文件读取下载文件的存储路径,在配置文件的尾部添加文件存储路径配置项:

# 下载文件存储路径配置项
FILES_STORE = os.path.join(os.path.dirname(os.path.dirname(__file__)),"source")

该配置项使用了os模块,因此需要在配置文件头部导入os模块。下载文件存储路径设置为爬虫项目目录下的source,source目录爬虫会自动创建。

6、 编辑爬虫文件

修改SpiderMatplotlibSpider爬虫类,代码如下:

import scrapy
 
from matplotlib.items import MatplotlibItem
 
 
class SpiderMatplotlibSpider(scrapy.Spider):
    name = 'spider_matplotlib'
    allowed_domains = ['www.matplotlib.org']
    start_urls = ['https://www.matplotlib.org/gallery/index.html']
 
    def parse(self, response):
        # 获取爬取下来的网页代码
        html = response.text
        # 提取案例代码网页链接
        source_link = response.xpath("//a[contains(@href,'-py')]/@href").extract()
        # 处理提取的案例代码网页链接
        for link in source_link:
            # 获取link的绝对URL
            url = response.urljoin(link)
            # 发送request请求
            request = scrapy.Request(url, callback=self.parse_source_link, dont_filter=True)
            yield request
 
 
    # 处理案例代码网页
    def parse_source_link(self, response):
        #实例化MatplotlibItem对象
        item = MatplotlibItem()
        # 从URL提取案例分类
        catalog = response.url.split('/')[-2]
        # 赋值Item类的catalog数据项
        item["catalog"] = catalog
        # 提取文件下载URL
        down_link = response.xpath("//a[@class='reference download internal']/@href").extract()
        # 相对URL转换为绝对URL
        item["file_urls"] = [response.urljoin(link) for link in down_link]
        # 使用yield语句返回item给parse的调用者
        yield item

parse()方法用于提取index.html所有案例网页URL,对每个案例网页URL发送request请求。

parse_source_link()方法解析案例网页,提取案例分类和文件下载URL,并创建Item实例对象进行后续处理。

7、 运行爬虫

在PyCharm环境中,若编写py文件来运行爬虫程序,PyCharm可能不识别Scrapy命令。

具体运行方法:

(1)在PyCharm环境中,打开终端窗口,在终端窗口将当前工作目录切换到爬虫项目目录(课程案例是在D盘splider目录下):

D:\splider\matplotlib\matplotlib>

(2)输入Scrapy运行爬虫命令:

scrapy crawl spider_matplotlib -o items.json

爬虫运行完成后,会将下载文件存储到爬虫项目目录下的source目录,在source目录内建立分类目录,分类目录是下载的文件。

项目全部代码见课程资源(unit4\ matplotlib)。

代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论