Python 萌新 - 花10分钟学爬虫

news2024/11/27 20:09:27

前言
Python 新手入门很多时候都会写个爬虫练手,本教程使用 Scrapy 框架,帮你简单快速实现爬虫,并将数据保存至数据库。在机器学习中数据挖掘也是十分重要的,我的数据科学老师曾经说过,好算法不如好数据。

Python助学大礼包点击免费获取

目录

  • 一级目录
    • 二、数据模型:items
      • 三、爬虫:spider
      • 四、数据处理:pipelines

一级目录

安装 Scrapy (系统默认安装了 Python):

$ pip install Scrapy

在当前目录新建工程

$ scrapy startproject yourproject

新建工程文件结构如下:

yourproject/
----|scrapy.cfg             # 部署配置文件
    |yourproject/           # 工程目录
    |----__init__.py
    |----items.py           # 项目数据文件
    |----pipelines.py       # 项目管道文件
    |----settings.py        # 项目设置文件
    |----spiders/           # 我们的爬虫 目录
        |----__init__.py    # 爬虫主要代码在这里    

简单的爬虫主要使用了 spiders、items、pipelines,age这三个文件:

  • spider :爬虫的主要逻辑。
  • items :爬虫的数据模型。
  • pipelines : 爬虫获取到的数据的加工工厂,可以进行数据筛选或保存。

二、数据模型:items

分析网页的信息我们可以看到网页主体是一个列表,列表每一行都包含可一句引用、作者名字、标签等信息。作者名右边点击(about)可以看到作者的详细信息,包括介绍、出生年月日、地点等等。根据上面的数据,我们可以先创建如下数据模型:

items.py

import scrapy

# quote 我们要爬取的主体
class QuoteItem(scrapy.Item):
    text = scrapy.Field()
    tags = scrapy.Field()
    author = scrapy.Field()

    next_page = scrapy.Field()
    pass
    
# quote 的作者信息 对应 QuoteItem.author
class AuthorItem(scrapy.Item):
    name = scrapy.Field()
    birthday = scrapy.Field()
    address = scrapy.Field()
    description = scrapy.Field()
    pass

所有的模型必须继承scrapy.Item,完成这一步我们就可以开始写爬虫的逻辑了。

# 完整的 QuoteItem 数据结构示例
{
    text,
    tags,
    author:{
        name,
        birthday,
        address,
        description
    }
}

三、爬虫:spider

在这里插入图片描述
既然是爬虫,自然需要去爬取网页,爬虫部分的几个要点:

  1. 引入你创建的数据模型
  2. 首先爬虫类要继承scrapy.Spider
  3. 设置爬虫的名字name,启动爬虫时要用。
  4. 将你要爬取的网址放入start_requests(),作为爬虫的起点。
  5. 爬取的网页信息成功后,在的请求响应parse()中解析。

spiders/init.py

  • 在顶部引入创建的数据模型。
import scrapy
from ScrapySample.items import QuoteItem
from ScrapySample.items import AuthorItem
  • 爬虫类,name->爬虫名字,allowed_domains->爬取网页的白名单。
class QuotesSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["quotes.toscrape.com"]

start_requests()中记录你要爬取的网址。
可以只放入一个网址,然后让爬虫自己爬取起始网址中下一页的链接。也可以在这里把所有需要爬的网址直接放入,比如说page一般是从1开始,并且有序的,写一个for循环可以直接输入所有页面的网址。
本文使用的是让爬虫自己去爬取下一页网址的方式,所以只写入了一个起始网址。

    def start_requests(self):
        urls = [
            'http://quotes.toscrape.com/page/1/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)
  • 如下代码,爬取网页成功之后,我们要分析网页结构,找到我们需要的数据。

我们先来看XPath语法,//div[@class=“col-md-8”]/div[@class=“quote”:这是表示查找 class 为"col-md-8"的 div 节点下的一个子节点,并且子节点是一个 class 为“quote” div 节点。如果在当前页面找到了这样一个节点,则返回节点信息,如果没有找到则返回None

    def parse(self, response):
        # 通过查看器,找到列表所在的节点
        courses = response.xpath('//div[@class="col-md-8"]/div[@class="quote"]')

        for course in courses:
            # 将数据模型实例化 并从节点中找到数据填入我们的数据模型
            item = QuoteItem()
            # 轮询 course 节点下所有 class 为 "text" 的 span 节点,获取所有匹配到的节点的 text() ,由于获取到的是列表,我们默认取第一个。
            item['text'] = course.xpath('.//span[@class="text"]/text()').extract_first()
            item['author'] = course.xpath('.//small[@class="author"]/text()').extract_first()
            item['tags'] = course.xpath('.//div[@class="tags"]/a/text()').extract()

            # 请求作者详细信息
            author_url = course.xpath('.//a/@href').extract_first()
            # 如果作者介绍的链接不为空 则去请求作者的详细信息
            if author_url != '':
                request = scrapy.Request(url='http://quotes.toscrape.com'+author_url, dont_filter=True, callback=self.authorParse)
                # 将我们已经获取到的 QuoteItem 传入该请求的回调函数 authorParse(),在该函数内继续处理作者相关数据。
                request.meta['item'] = item
                yield request
        
        # 继续爬向下一页 该函数具体实现下面会分析
        next_page_request = self.requestNextPage(response)
        yield next_page_request
  • 爬取作者详细信息
    成功获取作者详细信息 AuthorItem 后并且赋值给 QuoteItem 的属性 author ,这样一个完整的引述信息 QuoteItem 就组装完成了。
    def authorParse(self, response):
        # 先获取从 parse() 传递过来的 QuoteItem
        item = response.meta['item']
        # 通过查看器,找到作者详细信息所在节点
        sources = response.xpath('//div[@class="author-details"]')
        
        # 实例化一个作者信息的数据模型
        author_item = AuthorItem()
        # 往作者信息模型填入数据
        for source in sources:
            author_item['name'] = source.xpath('.//h3[@class="author-title"]/text()').extract_first()
            author_item['birthday'] = source.xpath('.//span[@class="author-born-date"]/text()').extract_first()
            author_item['address'] = source.xpath('.//span[@class="author-born-location"]/text()').extract_first()
            author_item['description'] = source.xpath('.//div[@class="author-description"]/text()').extract_first()
    
        # 最后将作者信息 author_item 填入 QuoteItem 
        item['author'] = author_item
        # 保存组装好的完整数据模型
        yield item
  • 爬虫自己找到出路(下一页网页链接)

通过查看器我们可以找到下一页按钮元素,找到该节点并提取链接,爬虫即奔向下一个菜园。

    def requestNextPage(self, response):
        next_page = response.xpath('.//li[@class="next"]/a/@href').extract_first()
        # 判断下一个是按钮元素的链接是否存在
        if next_page is not None:
            if next_page != '':
                return scrapy.Request(url='http://quotes.toscrape.com/'+next_page, callback=self.parse)
        return None

爬虫的主要逻辑到这里就结束了,我们可以看到,一小段代码就可以实现一个简单的爬虫。一般主流网页都针对防爬虫做了一些处理,实操过程中也许并不会这么顺利,我们可能需要模仿浏览器的User-Agent,或者做访问延时防止请求过于频繁等等处理。

四、数据处理:pipelines

pipelines是 Scrapy 用来后续处理的管道,可以同时存在多个,并且可以自定义顺序执行,通常用来做数据处理和数据保存。我们需要在 settings.py文件中设置需要需要执行的管道和执行顺序。

# 在 settings.py 加入下面的代码
ITEM_PIPELINES = {
   'ScrapySample.pipelines.ScrapySamplePipeline': 300,
}

在这里我只使用了一个管道ScrapySamplePipeline,用来将数据保存到数据库当中,后面的数字300是表示该管道的优先级,数字越小优先级越高。
由于我们要保存数据到数据库,所以我们需要先在本地搭建起数据库服务,我这里用的是MySQL,如果没有搭建的小伙伴可以下个 MAMP 免费版本,安装好傻瓜式操作一键启动Apache、MySQL服务。当然,数据库和表还是要自己建的。

# 在 pipelines.py 中加入数据库配置信息
config = {
    'host': '127.0.0.1',
    'port': 8081,
    'user': 'root',
    'password': 'root',
    'db': 'xietao',
    'charset': 'utf8mb4',
    'cursorclass': pymysql.cursors.DictCursor,
}

我们可以在init()函数里做一些初始化工作,比如说连接数据库。
然后process_item()函数是管道处理事件的函数,我们要在这里将数据保存入数据库,我在这个函数里写了一些插入数据库操作。
close_spider()函数是爬虫结束工作时候调用,我们可以在这里关闭数据库。

class ScrapySamplePipeline(object):

    def __init__(self):
        # 连接数据库
        self.db = sql.connect(**config)
        self.cursor = self.db.cursor()

    def process_item(self, item, spider):
        # 先保存作者信息
        sql = 'INSERT INTO author (name, birthday, address, detail) VALUES (%s, %s, %s, %s)'
        self.cursor.execute(sql, (item['author']['name'], item['author']['birthday'], item['author']['address'], item['author']['description']))
        # 获取作者id
        author_id = self.cursor.lastrowid

        # 保存引述信息
        sql = 'INSERT INTO spider (text, tags, author) VALUES (%s, %s, %s)'
        self.cursor.execute(sql, (item['text'], ','.join(item['tags']), author_id))
        self.db.commit()

    # 即将结束爬虫
    def close_spider(self, spider):
        self.db.close()
        self.cursor.close()
        print('close db')

如果不需要保存数据库或者对数据处理的话, close_spider()pipelines这部分是可以忽略的。这个时候在命令行切换到工程目录下,输入开始执行爬虫命令:

$ scrapy crawl quotes

部分不保存到数据库的小伙伴可以使用下方命令,将爬取的数据以 Json 格式导出到该工程目录下。

$ scrapy crawl quotes -o quotes.json

最后贴上数据库数据成功录入的截图。

在这里插入图片描述
请添加图片描述

↓ ↓ ↓ 加下方名片找我,直接拿源码还有案例 ↓ ↓ ↓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/559068.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

理光打印机连接电脑后不打印的原因及解决方法

理光打印机在使用时,可能会出现正常连接上理光打印机却没有反应的情况,出现无法打印的情况,下面,驱动人生为大家带来理光打印机连接后不打印的解决方案。 驱动人生分析,一般遇到理光打印机连接后不打印的情况&#xf…

第一行代码 第十一章 基于位置的服务

第11章 基于位置的服务 在本章中,我们将要学习一些全新的Android技术,这些技术有别于传统的PC或Web领域的应用技术,是只有在移动设备上才能实现的。 基于位置的服务(Location Based Service)。由于移动设备相比于电脑…

Prompt Engineering | 编写prompt的原则与策略

😄 为了更好地与大模型(e.g. chatgpt)更好的交流,一起来学习如何写prompt吧!😄 文章目录 1、简介2、编写prompt的原则与策略2.1、编写清晰、具体的指令2.1.1、策略一:使用分隔符清晰地表示输入的…

js 解析map (处理后端返回对象拼接)

返回的数据 需要的展示效果 解析如下: { title: ‘销售属性’, align: ‘left’, dataIndex: ‘xsshuxing’, width: 200, render(value, record) { let keyValue ‘’; { for (var key in record.otherAttr) { console.log(‘属性:’ key ‘,值&…

EIS-Net

我们提出了一种新的领域泛化框架(称为EISNet),该框架利用来自多源领域图像的外在关系监督和内在自我监督学习,学习如何同时在不同领域中进行泛化。 具体而言,我们采用多任务学习范式,通过特征嵌入来构建我…

AI智慧安监视频平台EasyCVR视频出现不能播放的情况排查与解决

EasyCVR基于云边端协同,可支持海量视频的轻量化接入与汇聚管理。平台兼容性强、拓展度高,可提供视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、H.265自动转码、平台级联等功能。 有用户反…

如何动态生成列表视图?

UE5 插件开发指南 前言0 什么是列表视图?1 如何动态生成?1.0 指定ListView生成的条目前言 这里将其拆分成两个问题来分析: (1)什么是列表视图? (2)如何动态生成? 0 什么是列表视图? 列表视图就是用来展示一系列对象的UI列表,在UE编辑器的UserWidget设计窗口中可以找到…

linux 安装 ffmpeg

linux 安装 ffmpeg windows上安装,直接下载压缩包解压。linux安装,找了半天各种技术文章,说最好编译安装,按照步骤安装编译环境编译成功了,但是使用的时候总要安装各种外部库,转码转不了等等问题...... 最…

城市生命线监测系统包括哪些内容?

城市排水、供水、燃气、供热、桥梁、隧道、综合管廊等基础设施是城市正常运转的基石,被称为“城市生命线”。城市生命线一旦出现故障或事故,将会给城市和居民带来巨大的经济和生活损失。通过对城市生命线的实时监测和预警,可以及时发现潜在的…

第十五届“中国电机工程学会杯”数学建模竞赛

第十五届电工杯5月26号就要开始啦,今天给大家回顾第十四届全国大学生电工数学建模竞赛A题,主要从赛题重述和问题分析与代码实战展开。第十五届全国大学生电工数学建模竞赛已经开始报名了哦,后续我也会分享对应的建模思路哦,大家记…

Leetcode452. 用最少数量的箭引爆气球

Every day a Leetcode 题目来源:452. 用最少数量的箭引爆气球 解法1:排序 贪心 题解:用最少数量的箭引爆气球 我们首先随机地射出一支箭,再看一看是否能够调整这支箭地射出位置,使得我们可以引爆更多数目的气球。…

CVPR论文解读 | 点云匹配的旋转不变变压器

原创 | 文 BFT机器人 传统的手工特征描述符通常具有内在的旋转不变性,但是最近的深度匹配器通常通过数据增强来获得旋转不变性。 然而,由于增强旋转数量有限,无法覆盖连续SO(3)空间中所有可能的旋转,因此这…

VC6.0的工程设置解读Project--Settings

做开发差不多一年多了,突然感觉对VC的工程设置都不是很清楚,天天要和VC见面,虽然通常情况下一般都不会修改工程设置,但是还是有必要对它的一些设置项的来龙去脉有一定的了解,所以狂查资料,稍作整理&#xf…

(仿真)创建 URDF 机器人模(1)

继上一篇基础篇的结束,不用看以前的也可以,这里是不受前面的影响的。 如果你没有这个目录,就创建一个catkin_ws文件夹 然后里面再一个src文件夹就ok了,我在基础篇第一篇的时候就有这个文件夹了,所有我现在是直接进入 …

【 计算机组成原理 】第七章 外围设备

系列文章目录 第一章 计算系统概论 第二章 运算方法和运算器 第三章 多层次的存储器 第四章 指令系统 第五章 中央处理器 第六章 总线系统 第七章 外围设备 第八章 输入输出系统 文章目录 系列文章目录前言第七章 外围设备7.1 外围设备概述7.1.1 外围设备的一般功能7.1.2 外围…

zabbix安装部署、三分钟分钟部署zabbix监控(超详细)

zabbix安装部署 1,快速安装部署zabbix2,一键脚本安装zabbix 1,快速安装部署zabbix 1,关闭防火墙,selinux systemctl stop firewalld systemctl disable firewalld setenforce 0 #临时 sed -i s/SELINUXenforcing/SE…

运维宝典大全

运维宝典大全 网络拓展Linux 概述什么是LinuxUnix和Linux有什么区别?什么是 Linux 内核?Linux的基本组件是什么?Linux 的体系结构BASH和DOS之间的基本区别是什么?Linux 开机启动过程?Linux系统缺省的运行级别&#xff…

Jmeter性能测试 -3 Jmeter使用中的一些问题

请求内容出现乱码的处理方法 1 内容编码:utf-8 2 请求头添加编码 Content-Type: application/json;charsetutf-8 3 请求体为参数类型时,勾选参数“编码”,编码为urlencoded编码。当参数值为非字符(汉字、特殊符号)时…

全面了解Java连接MySQL的基础知识,快速实现数据交互

全面了解Java连接MySQL的基础知识,快速实现数据交互 1. 数据库的重要性2. MySQL数据库简介2.1 MySQL数据库的基本概念2.2 MySQL的基本组成部分包括服务器、客户端和存储引擎。2.3 安装MySQL数据库2.3.1安装MySQL数据库2.3.2 下载MySQL安装程序2.3.3 运行MySQL安装程…

API接口|了解API接口测试|API接口测试指南

part1.什么是API接口 API接口是指应用程序接口(Application Programming Interface),它是一组定义、控制和描述软件程序中不同组件之间交互的方式和规则。 API接口允许不同的软件系统之间进行信息共享和相互访问,而无需了解在其…