Python爬虫实战

2023-10-29

在本篇博客中,我们将使用Scrapy框架完成一个入门爬虫程序。

  • 在命令行创建scrapy项目

首先在命令行进入PyCharm的项目目录,然后执行 scrapy startproject 项目名(如ScrapyExample),生产爬虫项目。会自动生成项目结构和一些文件:

  • 在命令行常见Spider

Spider 是一个自定义的类, Scrapy 用它来从网页里抓取内容,并解析抓取的结果。这个类必须继承Spider 类(scrapy.Spider) ,需定义Spider 的名称和起始请求,以及解析爬取结果的方法。

进入之前生成的spiders目录,执行下面的命令:

命令:scrapy  genspider  Spider名称  网站域名

例:scrapy genspider quotes quotes.toscrape.com

此时会在spiders目录下生成一个以爬虫名字命名的.py文件:

  • 创建Item

Item 是保存爬取数据的容器。创建Item 需要继承scrapy.Item 类,并且定义类型为scrapy.Field 的字段。

首先我们来看一下,我们之前要爬取的那个网站是什么,打开http://quotes.toscrape.com/:

网站上主要是一些名人名言,每一条包含三个部分:名言、作者、标签。

接下来我们要自定义items.py(原本是空的,只有主要结构),定义我们想要的字段:

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class QuoteItem(scrapy.Item):#类名默认是项目名+Item,可以修改.如QuoteItem
    # define the fields for your item here like:
    # name = scrapy.Field()
    text = scrapy.Field() #名言
    author = scrapy.Field() #作者
    tags = scrapy.Field() #标签
    pass
  • 编辑spider中的parse方法(用于解析response)

对response 变量包含的内容进行解析,可以使用CSS选择器或Xpath选择器,解析结果赋值给Item中的字段。quotes.py:

# -*- coding: utf-8 -*-
import scrapy
from ScrapyExample.items import QuoteItem  #把QuoteItem类导入 二者建立关联


class QuotesSpider(scrapy.Spider):#自定义爬虫类 继承scrapy.Spider
    name = 'quotes'     #爬虫名字
    allowed_domains = ['quotes.toscrape.com']   #待爬取网站域名
    start_urls = ['http://quotes.toscrape.com/']  #待爬取网站的起始网址

    def parse(self, response):  #解析/提取规则
        '''
        <div class="quote" itemscope="" itemtype="http://schema.org/CreativeWork">
        <span class="text" itemprop="text">“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”</span>
        <span>by <small class="author" itemprop="author">Albert Einstein</small>
        <a href="/author/Albert-Einstein">(about)</a>
        </span>
        <div class="tags">
            Tags:
            <meta class="keywords" itemprop="keywords" content="change,deep-thoughts,thinking,world">

            <a class="tag" href="/tag/change/page/1/">change</a>

            <a class="tag" href="/tag/deep-thoughts/page/1/">deep-thoughts</a>

            <a class="tag" href="/tag/thinking/page/1/">thinking</a>

            <a class="tag" href="/tag/world/page/1/">world</a>

        </div>
    </div>
        '''
        quotes = response.css('.quote') #获取当页所有名言 div标签
        for quote in quotes:
            item = QuoteItem()
            #.text css选择器 ::text获取节点的文本内容,结果是列表,用extract_first()获取第一个元素
            item['text'] = quote.css('.text::text').extract_first()
            item['author'] = quote.css('.author::text').extract_first()
            item['tags'] = quote.css('.tags .tag::text').extract() #获取整个列表
            yield item

        # 下一个要爬取的页面url
        '''
        <li class="next">
                <a href="/page/2/">Next <span aria-hidden="true">→</span></a>
            </li>
        '''
        next = response.css('.next a::attr(href)').extract_first()
        url = response.urljoin(next)
        yield scrapy.Request(url=url,callback=self.parse)
        # 当请求完成后,引擎将响应作为参数传递给回调函数 继续解析
  • 在命令行运行

在spiders目录下执行下面的命令。

scrapy crawl Spider名称

运行并显示结果,例:scrapy crawl quotes

scrapy crawl Spider名称 –o 文件名

运行并将结果保存到文件(json、csv、xml等),例:scrapy crawl quotes –o output.json

  • 进阶

使用 Item Pipeline

如果想进行更复杂的操作,如将结果保存到MongoDB 数据库,或者筛选某些有用的Item ,则可以定义Item Pileline 来实现。当Item 生成后,它会自动被送到Item Pipeline 进行处理,常用ItemPipeline 来做如下操作:

1)清理HTML 数据

2)验证爬取数据,检查爬取字段

3)查重并丢弃重复内容

4)将爬取结果保存到数据库

实现 Item Pipeline(修改pipelines.py)

定义一个类并实现process_item(),必须返回包含数据的字典或Item 对象,或者抛出Dropltem 异常。process_item()方法主要用到了两个参数:一个参数是item ,每次Spider 生成的Item 都会作为参数传递过来;一个参数是spider ,就是Spider 的实例。启用Item Pipeline后, Item Pipeline 会自动调用process_item()方法。

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

import pymongo
from scrapy.exceptions import DropItem

class ScrapyexamplePipeline(object):
    def process_item(self, item, spider):
        return item

#定义Item处理的类 筛掉text长度大于50的Item
class TextPipeline(object):

    def __init__(self):
        self.limit = 50

    #该方法必须定义,而且必须要有item和spider两个参数
    #其他方法可以随便写
    def process_item(self,item,spider):
        if item['text']:
            if len(item['text']) > self.limit:
                item['text'] = item['text'][0:self.limit].rstrip() + '...'
            return item
        else:
            return DropItem('Missing Text')

#定义数据库存储类 将数据存储到mongodb数据库
class MongoPipeline(object):

    def __init__(self, mongo_uri, mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db

    # 从配置文件setting.py中获取mongo_uri,mongo_db 需要自己在setting.py中定义
    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            mongo_uri=crawler.settings.get('MONGO_URI'),
            mongo_db=crawler.settings.get('MONGO_DB')
        )

    # 连接并打开数据库
    def open_spider(self, spider):
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]

    # 该方法必须定义,而且必须要有item和spider两个参数 其他方法可以随便写
    def process_item(self, item, spider):
        name = item.__class__.__name__
        self.db[name].insert(dict(item))  # 将数据插入集合 要转换为字典形式 键值对
        return item

    # 关闭连接
    def close_spider(self, spider):
        self.client.close()

注意要把pipeline在setting.py里面进行注册,告诉scrapy增加了pipeline(把下面的代码加到setting.py中):

ITEM_PIPELINES = {
    'ScrapyExample.pipelines.TextPipeline': 300,
    'ScrapyExample.pipelines.MongoPipeline': 400,
}

再运行scrapy crawl quotes,便可把数据存到mongodb数据库中,可以选择从数据库中导出为各种形式的文件。

爬取效果:

  • 修改User-Agent

Scrapy 发送的Request 使用的User-Agent 是Scrapy/1.6.0(+http: //scrapy.org),

由Scrapy 内置的UserAgentMiddleware 设置, UserAgentMiddleware 的源码如下:

两种方式:

修改settings里面的USER-AGENT变量(推荐)

通过Downloader Middleware 的process_request()方法修改

在middlewares.py 中添加下面这个类,对Downloader Middleware做修改:

​class RandomUserAgentDownloaderMiddleware(object):
    def __init__(self):
        self.user_agents = [
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
            'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.5959.400 SLBrowser/10.0.3544.400',
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134'
        ]

    def process_request(self, request, spider):
        request.headers['User-Agent'] = random.choice(self.user_agents)

    def process_response(self, request, response, spider):
        response.status = 200
        return response

​

 第一种修改方式:

在setting.py中添加:

USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'

第二种修改方式: 

之前在middlewares.py 中添加了RandomUserAgentDownloaderMiddleware类,在settings.py中对他进行注册:

DOWNLOADER_MIDDLEWARES = {
    'ScrapyExample.middlewares.RandomUserAgentDownloaderMiddleware': 543,
}

在执行 scrapy crawl quotes

完整项目

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python爬虫实战 的相关文章

  • 如何在scrapy中发出请求之前更改请求url?

    我需要在下载响应之前修改我的请求网址 但我无法改变它 即使使用修改请求网址后request replace url new url the process response打印未修改的 url 这是中间件的代码 def process re
  • 用scrapy一一爬取网站列表

    我正在尝试抓取网站列表scrapy 我尝试将网站网址列表作为start urls 但后来我发现我买不起那么多内存 有什么办法可以设置scrapy一次抓取一两个网站 您可以尝试使用concurrent requests 1以免数据超载 htt
  • 从 Django 调用 Scrapy Spider

    我有一个项目 在同一工作区中包含 django 和 scrapy 文件夹 my project django project django project settings py app1 app2 manage py scrapy pro
  • Scrapy 阿拉伯字母返回一些奇怪的东西

    我在用scrapy关于阿拉伯字母和英文字母 英文字母完美地工作 然而 阿拉伯字母显示如下 gs300 2006 u0644 u0643 u0632 u0633 u062c u064a 有什么帮助吗 我正在使用 python 和 scrapy
  • 尝试伪造和轮换用户代理

    我正在尝试伪造用户代理并在 Python 中轮换它们 我在网上找到了一个关于如何使用 Scrapy 执行此操作的教程scrapy 用户代理 https github com svetlyak40wt scrapy useragents包裹
  • Scrapy Python Craigslist Scraper

    我正在尝试使用 Craigslist 分类广告Scrapy提取待售物品 我能够提取日期 帖子标题和帖子 URL但提取时遇到问题price 由于某种原因 当前代码提取all的价格 但是当我删除 在价格范围之前查找价格字段返回为空 有人可以查看
  • 使用scrapy到json文件只得到一行输出

    好吧 我对一般编程很陌生 并且具体使用 Scrapy 来实现此目的 我编写了一个爬虫来从 pinterest com 上的 pin 获取数据 问题是我以前从我正在抓取的页面上的所有引脚获取数据 但现在我只获取第一个引脚的数据 我认为问题出在
  • 如何使用 BeautifulSoup4 获取
    标记之前的所有文本

    我正在尝试为我的应用程序抓取一些数据 我的问题是我需要一些 HTML 代码如下 tr td This a class tip info href blablablablabla is a first a sentence br This a
  • 访问 Scrapy 内的 django 模型

    是否可以在 Scrapy 管道内访问我的 django 模型 以便我可以将抓取的数据直接保存到我的模型中 我见过this https scrapy readthedocs org en latest topics djangoitem ht
  • 在 Mac OS X 上安装 libxml2 时出现问题

    我正在尝试在我的 Mac 操作系统 10 6 4 上安装 libxml2 我实际上正在尝试在 Python 中运行 Scrapy 脚本 这需要我安装 Twisted Zope 现在还需要安装 libxml2 我已经下载了最新版本 2 7 7
  • scrapy LinkExtractors 最终会得到唯一的链接吗?

    所以 我有一个包含很多文章和页码的页面 现在 如果我想提取一篇文章 我会使用 Rule LinkExtractor allow article html callback parse article 对于页面我使用这个规则 规则 LinkE
  • Scrapy仅抓取网站的一部分

    您好 我有以下代码来扫描给定站点中的所有链接 from scrapy item import Field Item from scrapy contrib spiders import CrawlSpider Rule from scrap
  • 我的扩展中未收到 Scrapy Spider_idle 信号

    我在几个蜘蛛之间有共同的行为spider idle正在接收信号 我想将此行为移至扩展中 我的分机已经监听spider opened and spider closed信号成功 但是 那spider idle未收到信号 这是我的扩展 为简洁起
  • 如何使用scrapy检查网站是否支持http、htts和www前缀

    我正在使用 scrapy 来检查某些网站是否工作正常 当我使用http example com https example com or http www example com 当我创建 scrapy 请求时 它工作正常 例如 在我的pa
  • scrapy蜘蛛如何将值返回给另一个蜘蛛

    我正在爬行的网站包含许多玩家 当我点击任何玩家时 我都可以进入他的页面 网站结构是这样的
  • 如何添加剧作家的等待时间

    我正在将 scrapy 与 playwright 集成 但发现自己在单击后添加计时器时遇到困难 因此 当我点击后截取页面的屏幕截图时 它仍然挂在登录页面上 如何集成计时器以便页面等待几秒钟直到页面加载 选择器 onetrust close
  • Scrapy Splash,如何处理onclick?

    我正在尝试抓取以下内容 我能够收到响应 但我不知道如何访问以下项目的内部数据以抓取它 我注意到访问这些项目实际上是由 JavaScript 和分页处理的 这种情况我该怎么办 下面是我的代码 import scrapy from scrapy
  • scrapy-如何停止重定向(302)

    我正在尝试使用 Scrapy 抓取 url 但它会将我重定向到不存在的页面 Redirecting 302 to
  • 使用 Scrapy 抓取多个 URL

    如何使用 Scrapy 抓取多个 URL 我是否被迫制作多个爬虫 class TravelSpider BaseSpider name speedy allowed domains example com start urls http e
  • 如何从网址中删除查询?

    我正在使用 scrapy 抓取一个网站 该网站似乎将随机值附加到每个 URL 末尾的查询字符串 这将爬行变成了一种无限循环 我如何让 scrapy 忽略 URL 的查询字符串部分 See urllib urlparse http docs

随机推荐

  • RabbitMQ重复消费

    造成重复消费的原因 MQ向消费者推送message 消费者向MQ返回ack 告知所推送的消息消费成功 但是由于网络波动等原因 可能造成消费者向MQ返回的ack丢失 MQ长时间 一分钟 收不到ack 于是会向消费者再次推送该条message
  • three.js点材质(PointsMaterial)常用属性设置

    一 前景回顾 上一章节简单介绍了下怎么使用点材质和点对象创建物体点对象和点材质介绍 点材质和点对象基本运用示例代码 import as THREE from three 导入轨道控制器 import OrbitControls from t
  • Open3D 点云旋转的轴角表示法(python详细过程版)

    目录 一 算法原理 二 代码实现 三 结果展示 四 实验数据 一 算法原理 见 点云旋转的轴角表示法和罗德里格斯公式 二 代码实现 import open3d as o3d import numpy as np import copy 读取
  • 2020-10-09 Python基础学习第八天笔记

    文章目录 一 方法 1 私有方法和公共方法 2 property装饰器 3 继承 4 多态 polymorphism 一 方法 如果我们在类体中定义了多个重名的方法 只有最后一个方法有效 1 私有方法和公共方法 通常两个下划线开头的属性是私
  • python 关于文件操作——基础详细

    先看后赞 养成习惯 点赞收藏 人生辉煌 python 文件操作 文件读写 write read readlines readline 文件的相关操作 简单易懂 目录 1 文件操作 1 1 文件打开与关闭 1 1 1 打开文件 1 1 2 关
  • Unity3D的传送带和物体移动

    实现工厂流程的传送带传送物体的过程 包过一些基础的知识点 图片效果看原文 工程下载请看原文 https xygeng cn post 266 html 1 传送物体左右上下移动 gameObject transform Translate
  • sqlite3数据库交叉编译并移植到嵌入式开发环境步骤

    一 首先到http www sqlite org download html下载linux版本的源码 sqlite autoconf 3130000 tar gz 二 解压 tar xvzf sqlite autoconf 3130000
  • vue自定义指令---页面水印

    一些页面为了防止用户截图 可以添加水印 下面介绍以下思路 主要是创建一个新的节点作为水印 设置好水印的样式以后 再添加到目标节点上面去 水印 export default inserted el text let dom document
  • bootstrap导航栏鼠标移入展开

    bootstrap鼠标移入导航展开下拉菜单则加以下jq代码 function dropdown mouseover function this children a addClass show next ul addClass show d
  • 记录第一次部署streamlit应用

    网上相关教程很多 经过多方尝试 记录自己成功的方法 一 通过git将项目文件上传至github 参考教程 23条消息 部署项目到github Gao 的博客 CSDN博客 github部署项目 二 添加requirements 部署在Str
  • 计算机主机mac地址怎么查,怎么查看电脑的Mac地址

    第一种方法 利用dos命令查看Mac地址 1 点击 开始 菜单 在 搜索程序和文件 输入框 输入 cmd 会找到进入dos命令的cmd程序 然后回车 快捷方式 WIN R 在输入cmd 2 回车后 弹出命令符窗口 输入 ipconfig a
  • 技术积累 — Ellisys软件及抓包器用户使用指南

    一 前言 Ellisys号称是业界最先进的蓝牙 Wi Fi USB协议分析仪 支持低功耗蓝牙协议分析测试 支持蓝牙5低功耗以及Wi Fi的物联网应用 支持与原始频谱 UART SPI HCI 逻辑信号等同步的宽带蓝牙5低能耗BLE Wi F
  • [Linux]-进程间通信之消息队列

    目录 消息队列的概述 消息队列的API 1 获取系统唯一Key值 IPC键值 2 创建消息队列 2 1查看消息队列的一些Linux命令 2 2消息队列的创建 3 消息的发送以及定义 3 1 通过消息队列发送信息 4 信息的接收 5 通过消息
  • Codeforces Round #660 (Div. 2)1388C - Uncle Bogdan and Country Happiness (好题,条件判断,DFS)

    题目大意 国家有N个城市 1号城市为首都 有M个国民 每个国民都在首都工作 晚上返回家中 给定每个城市有多少国民居住 每个城市都有一个心情检测器 当国民经过城市时 心情检测器根据国民的心情加减1 但是心情检测器并不精确 所以要求你去判断在所
  • 汽车电子相关术语

    SOA SOA Service Oriented Architecture 面向服务的架构 是一种在计算机环境中设计 开发 部署和管理离散模型的方法 是由Garnter1996年提出的概念 将应用程序的不同功能单元 称为服务 进行拆分 并通
  • NeRF论文翻译笔记

    分享 NeRF神经辐射场理解 深兰深延AI的博客 CSDN博客 神经辐射场 githubNeRF总结 https github com yenchenlin awesome NeRF 目录 摘要 1 介绍 2 相关工作 2 1 神经三维形状
  • ModuleNotFoundError: No module named 'exceptions'

    ModuleNotFoundError No module named exceptions 意味着你在你的代码中尝试使用了一个名为 exceptions 的模块 但是你的程序运行环境中找不到这个模块 这可能是因为这个模块没有安装 或者是你
  • MPC学习记录

    参考 无人驾驶车辆模型预测控制 第二版 第四章详细学习 算法部分 总系学不废的博客 CSDN博客 控制 模型预测控制MPC08 01总结修正 105664978 哔哩哔哩 bilibiliMPC 3 常用车辆模型 MATLAB 无人驾驶车辆
  • 用python计算工程量_使用python计算vintage

    coding utf 8 Created on Mon Jan 14 18 57 19 2019 author hinnc importnumpy as npimportpandas as pd from pandas tseries of
  • Python爬虫实战

    在本篇博客中 我们将使用Scrapy框架完成一个入门爬虫程序 在命令行创建scrapy项目 首先在命令行进入PyCharm的项目目录 然后执行 scrapy startproject 项目名 如ScrapyExample 生产爬虫项目 会自