Python - 爬虫;Scrapy框架(一)

news2025/5/11 3:29:28

框架,就相当于一个封装了很多功能的结构体,它帮我们把主要的结构给搭建好了,我们只需往骨架里添加内容就行。

Scrapy是适用于Python的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy是网页抓取框架,支持CSS选择器和XPath,可将数据以多种格式(如CSV、JSON、XML)导出。包含Spiders、Pipelines、DownloaderMiddleware等组件,具有高效性、灵活性和强大选择器。应用于 数据挖掘、监测和自动化测试,数据采集、SEO、社交媒体监测等。

Scrapy官网:Scrapy | A Fast and Powerful Scraping and Web Crawling Framework

一、scrapy工作原理

1、scrapy核心组件

1、引擎(EGINE):引擎负责控制整个数据抓取过程,调度中间件和协调各个组件。

2、调度器(SCHEDULER):负责接收来自引擎的请求,并分配给下载器。用来接受引擎发过来的请求,压入队列中,并在引擎再次请求的时候返回。可以想像成一个URL的优先级队列, 由它来决定下一个要抓取的网址是什么,同时去除重复的网址

3、下载器(DOWLOADER):负责处理引擎与下载器之间的请求和响应。用于下载网页内容,并将网页内容返回给EGINE,下载器是建立在twisted这个高效的异步模型上的

4、爬虫(SPIDERS):负责编写用于抓取网站的代码。SPIDERS是开发人员自定义的类,用来解析responses,并且提取items,或者发送新的请求

5、项目管道(ITEM PIPLINES):负责处理抓取到的数据,如清洗、验证和存储。在items被提取后负责处理它们,主要包括清理、验证、持久化(比如存到数据库)等操作 下载器中间件(Downloader Middlewares)位于Scrapy引擎和下载器之间,主要用来处理从EGINE传到DOWLOADER的请求request,已经从DOWNLOADER传到EGINE的响应response, 你可用该中间件做以下几件事:  

(1) process a request just before it is sent to the Downloader (i.e. right before Scrapy sends the request to the website);  

(2) change received response before passing it to a spider;  

(3) send a new Request instead of passing received response to a spider;  

(4) pass response to a spider without fetching a web page;  

(5) silently drop some requests.

6、爬虫中间件(Spider Middlewares):位于EGINE和SPIDERS之间,主要工作是处理SPIDERS的输入(即responses)和输出(即requests)

2、scrapy框架的执行过程

1、引擎向spiders要url
2、引擎将要爬取的url给调度器
3、调度器会将url件成请求对象放入到指定的队列中
4、从队列中出队—个请求
5、引擎将请求交给下载器进行处理
6、下载器发送请求获取互联网数据
7、下载器将数据返回给引擎
8、引擎将数据再次给到spiders
9、spiders通过xpath解析该数据,得到数据或者url
10、spiders将数据或者url给到引擎
11、引擎判断是数据还是url, 是数据,交给管道(item pipeline )处理进行存储, 是url交给调度器处理

二、scrapy安装使用

pip install scrapy

: Scrapy的底层依赖于lxml,twisted,openssl等,涉及到C库,有可能会安装失败

如果出错提示to update pip,请升级pip

python -m pip install --upgrade pip

(一)示例网站爬取

文档:Scrapy 2.12 documentation — Scrapy 2.12.0 documentation

示例爬虫网站:https://quotes.toscrape.com

 创建一个quotes_spider.py 文件

import scrapy

'''
把它放在一个文本文件中,将其命名为quotes_spider.py,然后使用runspider命令运行(终端Terminal中运行即可)
scrapy runspider quotes_spider.py -o quotes.jsonl 以Json文件输出Json格式
scrapy runspider quotes_spider.py
'''

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'https://quotes.toscrape.com/tag/humor/',
    ]

    def parse(self, response):
        # css请求
        # quotes = response.css('div.quote')
        # xpath请求
        quotes = response.xpath('//div[@class="quote"]')
        for quote in quotes:
            yield {
                # 'text': quote.css('span.text::text').get(),
                'text': quote.xpath('span[@class="text"]/text()').extract_first(),
                'author': quote.xpath('span/small/text').get(),
            }
        # next_page = response.css('li.next a::attr(href)').get()
        next_page = response.xpath('//li[@class="next"]/a/@href').extract_first
        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

在Terminal终端中运行如下命令 

scrapy runspider quotes_spider.py

 输出:

(.venv) PS D:\4Python\ProjectCode\FirstPythonProject\爬虫\Scrapy框架> scrapy runspider quotes_spider.py
2025-02-27 14:30:31 [scrapy.utils.log] INFO: Scrapy 2.12.0 started (bot: scrapybot)
2025-02-27 14:30:32 [scrapy.utils.log] INFO: Versions: lxml 5.3.1.0, libxml2 2.11.7, cssselect 1.2.0, parsel 1.10.0, 
w3lib 2.3.1, Twisted 24.11.0, Python 3.13.0 (tags/v3.13.0:60403a5, Oct  7 2024, 09:38:07) [MSC v.1941 64 bit (AMD64)], pyOpenSSL 25.0.0 (OpenSSL 3.4.1 11 Feb 2025), cryptography 44.0.1, Platform Windows-11-10.0.22631-SP0
2025-02-27 14:30:32 [scrapy.addons] INFO: Enabled addons:
[]
2025-02-27 14:30:32 [scrapy.utils.log] DEBUG: Using reactor: twisted.internet.selectreactor.SelectReactor
2025-02-27 14:30:32 [scrapy.extensions.telnet] INFO: Telnet Password: 8468e066f04ca85a
2025-02-27 14:30:32 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.corestats.CoreStats',
 'scrapy.extensions.telnet.TelnetConsole',
 'scrapy.extensions.logstats.LogStats']
2025-02-27 14:30:32 [scrapy.crawler] INFO: Overridden settings:
{'SPIDER_LOADER_WARN_ONLY': True}
2025-02-27 14:30:32 [scrapy.middleware] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.offsite.OffsiteMiddleware',
 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
 'scrapy.downloadermiddlewares.retry.RetryMiddleware',
 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',
 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware',
 'scrapy.downloadermiddlewares.stats.DownloaderStats']
2025-02-27 14:30:32 [scrapy.middleware] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
 'scrapy.spidermiddlewares.referer.RefererMiddleware',
 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
 'scrapy.spidermiddlewares.depth.DepthMiddleware']
2025-02-27 14:30:32 [scrapy.middleware] INFO: Enabled item pipelines:
[]
2025-02-27 14:30:32 [scrapy.core.engine] INFO: Spider opened
2025-02-27 14:30:32 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2025-02-27 14:30:32 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2025-02-27 14:30:34 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://quotes.toscrape.com/tag/humor/> (referer: None)
2025-02-27 14:30:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/tag/humor/>
{'text': '“The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.”', 'author': None}
2025-02-27 14:30:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/tag/humor/>
{'text': '“A day without sunshine is like, you know, night.”', 'author': None}
2025-02-27 14:30:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/tag/humor/>
{'text': '“Anyone who thinks sitting in church can make you a Christian must also think that sitting in a garage can make you a car.”', 'author': None}
2025-02-27 14:30:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/tag/humor/>
{'text': '“Beauty is in the eye of the beholder and it may be necessary from time to time to give a stupid or misinformed beholder a black eye.”', 'author': None}
2025-02-27 14:30:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/tag/humor/>
{'text': "“All you need is love. But a little chocolate now and then doesn't hurt.”", 'author': None}
2025-02-27 14:30:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/tag/humor/>
{'text': "“Remember, we're madly in love, so it's all right to kiss me anytime you feel like it.”", 'author': None}  
2025-02-27 14:30:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/tag/humor/>
{'text': '“Some people never go crazy. What truly horrible lives they must lead.”', 'author': None}
2025-02-27 14:30:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/tag/humor/>
{'text': '“The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.”', 'author': None}
2025-02-27 14:30:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/tag/humor/>
{'text': '“Think left and think right and think low and think high. Oh, the thinks you can think up if only you try!”', 'author': None}
2025-02-27 14:30:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/tag/humor/>
{'text': '“The reason I talk to myself is because I’m the only one whose answers I accept.”', 'author': None}        
2025-02-27 14:30:34 [scrapy.core.engine] INFO: Closing spider (finished)
2025-02-27 14:30:34 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 230,
 'downloader/request_count': 1,
 'downloader/request_method_count/GET': 1,
 'downloader/response_bytes': 10864,
 'downloader/response_count': 1,
 'downloader/response_status_count/200': 1,
 'elapsed_time_seconds': 1.458395,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2025, 2, 27, 6, 30, 34, 309091, tzinfo=datetime.timezone.utc),
 'item_scraped_count': 10,
 'items_per_minute': None,
 'log_count/DEBUG': 12,
 'log_count/ERROR': 1,
 'log_count/INFO': 10,
 'response_received_count': 1,
 'responses_per_minute': None,
 'scheduler/dequeued': 1,
 'scheduler/dequeued/memory': 1,
 'scheduler/enqueued': 1,
 'scheduler/enqueued/memory': 1,
 'spider_exceptions/TypeError': 1,
 'start_time': datetime.datetime(2025, 2, 27, 6, 30, 32, 850696, tzinfo=datetime.timezone.utc)}
2025-02-27 14:30:34 [scrapy.core.engine] INFO: Spider closed (finished)

以Json格式输出Json文件 

scrapy runspider quotes_spider.py -o quotes.jsonl #以Json文件输出Json格式

以csv格式输出csv文件  

 scrapy runspider quotes_spider.py -o quotes.csv -t csv

(二)Scrapy Tutorial

文档:Scrapy Tutorial — Scrapy 2.12.0 documentation

1、新建一个项目 scrapy startproject 项目名称

在pycharm的终端Terminal里

(1)首先切换到保存项目的根目录

(2)输入:

scrapy startproject 项目名称 # 如:scrapy startproject qianmu

构建了一个如下的文件目录:

project_name/
   scrapy.cfg:
   project_name/
       __init__.py
       items.py
       pipelines.py
       settings.py
       spiders/
           __init__.py
scrapy.cfg   项目的主配置信息。(真正爬虫相关的配置信息在settings.py文件中)
items.py     设置数据存储模板,用于结构化数据,如:Django的Model
pipelines    数据持久化处理
settings.py  配置文件,如:递归的层数、并发数,延迟下载等
spiders      爬虫目录,如:创建文件,编写爬虫解析规则

2、新建一个爬虫程序 scrapy genspider [爬虫程序名称] [爬虫目标网站域名-起始url]

也是在pycharm的终端Terminal里

(1)输入:cd 项目名称 #进入项目目录下

(2)生成spider文件,再输入:

# 生成spider文件;如:scrapy genspider usnews http://www.qianmu.org/
scrapy genspider [爬虫程序名称] [爬虫目标网站域名-起始url]

: 爬虫程序名称不要和爬虫项目名字重复!!!

此时就会在第二层的project_name文件夹下创建一个spider文件夹,spider文件夹下就会有一个‘爬虫应用程序名字.py的文件’,如下: 

project_name:
    project_name:
        spider:
            app_name.py

新生成的文件目录如下: 

此时会看到/spiders下新生成了一个usnews.py文件,文件代码如上图 

3、代码控制台scrapy crawl 爬虫名运行

import scrapy

'''
settings.py中有一个HTTPCACHE_ENABLED配置
# 启用HTTP请求缓存,下次请求同一URL时不再发送远程请求
HTTPCACHE_ENABLED = True
'''

class UsnewsSpider(scrapy.Spider):
    # 爬虫名字,用于运行爬虫时候使用的值,必须唯一
    name = "usnews"
    # 允许爬虫的URL必须在此字段内;genspider时可以指定;如qianmu.com意味www.qianmu.com和http.qianmu.org下的链接都可以爬取
    allowed_domains = ["www.qianmu.org"]
    # 爬虫的入口地址,可以多个
    start_urls = ["http://www.qianmu.org/2023USNEWS%E4%B8%96%E7%95%8C%E5%A4%A7%E5%AD%A6%E6%8E%92%E5%90%8D"]

    # 框架请求start_urls成功后,会调用parse方法
    def parse(self, response):
        # 提取链接,并释放
        links = response.xpath('//div[@id="content"]//tr[position()>1]/td/a/@href').extract()

        for link in links:
            if not link.startswith('http://www.qianmu.org'):
                link = 'http://www.qianmu.org/%s' % link
            # 请求成功以后,异步调用callback函数
            yield response.follow(link, self.parse_university)

    def parse_university(self, response):
        # 去除空格等特殊字符
        response = response.replace(body=response.text.replace('\t','').replace('\r\n', ''))
        data = {}
        data['name'] = response.xpath('//div[@id="wikiContent"]/h1/text()').extract_first()
        # data['name'] = response.xpath('//div[@id="wikiContent"]/h1/text()')[0]

        table = response.xpath('//div[@id="wikiContent"]//div[@class="infobox"]/table')
        if not table:
            return None
        table = table[0]
        keys = table.xpath('.//td[1]/p/text()').extract()
        cols = table.xpath('.//td[2]')
        # 当我们确定解析的数据只有1个结果时,可以使用extract_first()函数
        values = [' '.join(col.xpath('.//text()').extract()) for col in cols]
        if len(keys) == len(values):
            data.update(zip(keys, values))
        # yield出去的数据会被Scrapy框架接收,进行下一步处理;如果没有任何处理,则会打印到控制台
        yield data

PyCharm中的Terminal终端下,首先切换到usnews.py所在路径,然后执行命令

# 先切换到usnews.py文件所在目录下
# 运行名为usnews的爬虫 scrapy crawl 爬虫名
scrapy crawl usnews

# 将爬到的数据导出为Json文件
scrapy crawl usnews -o usnews.json

# 将爬到的数据导出为csv文件
scrapy crawl usnews -o usnews.csv -t csv

# 单独运行爬虫文件
scrapy runspider usnews.py

:爬虫名用于运行爬虫时候使用的值,必须唯一;即代码中【name】变量

(三)Scrapy调试

1、给项目单独建一个虚拟环境

切换到项目目录下,PyCharm终端Terminal运行

virtualenv env

如果遇到报错:virtualenv : 无法将“virtualenv”项识别为 cmdlet、函数、脚本文件或可运行程序的名称

virtualenv : 无法将“virtualenv”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一    
次。
所在位置 行:1 字符: 1
+ virtualenv env
+ ~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (virtualenv:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

(1)未安装 virtualenv,确认是否已经安装了 virtualenv。你可以通过以下命令来检查

pip list | findstr virtualenv

如果没有安装,可以通过以下命令进行安装

pip install virtualenv

(2)环境变量问题

确保 Python 和 Scripts 目录已经被添加到了系统的环境变量 PATH 中。通常情况下,Python 安装程序会询问你是否要将 Python 添加到环境变量,如果你选择了“Add Python to PATH”,那么这一步应该已经完成。

如果不确定,可以手动添加。假设你安装的 Python 版本是 3.9,路径为 C:\Python39\ 和 C:\Python39\Scripts\,你需要将这两个路径添加到系统环境变量 PATH 中 

(3)使用完整路径调用 virtualenv

如果暂时不想配置环境变量,可以直接使用 virtualenv 的完整路径来创建虚拟环境。例如,如果 virtualenv 安装在 C:\Python39\Scripts\virtualenv.exe,你可以这样运行:

C:\Python39\Scripts\virtualenv env

(4)确保你在正确的命令行工具中运行命令。对于 Windows,推荐使用 PowerShell 或者 CMD(命令提示符)。如果你使用的是其他终端模拟器,请确保它们正确配置了环境变量。

激活虚拟环境

首先,确保你的虚拟环境已经激活。在命令行中,你可以通过以下命令激活虚拟环境:

# 对于Windows
.\env\Scripts\activate
 
# 对于MacOS/Linux
source env/bin/activate

2、配置环境变量

(1)在菜单栏选中项目,点击【Edit Configurations...】

(2)填写Script path:该项目虚拟环境下安装的Scrapy路径;Parameters:crawl 项目名;Working directory:该项目所在路径

Windows下PyCharm中使用Scrapy创建一个项目,并查找env环境下Scrapy的路径

1、激活虚拟环境

首先,确保你的虚拟环境已经激活。在命令行中,你可以通过以下命令激活虚拟环境:

# 对于Windows
.\env\Scripts\activate
 
# 对于MacOS/Linux
source env/bin/activate

2、如果Scrapy还没有安装,你可以通过pip安装它:

pip install Scrapy

3、查找Scrapy脚本路径

(1)使用whichwhere命令

在命令行中,你可以使用which(Mac/Linux)或where(Windows)命令来查找Scrapy的脚本路径:

# MacOS/Linux

which scrapy

# Windows

where scrapy

(2)使用Python模块查找

你也可以通过Python模块查找Scrapy的安装位置:

import scrapy

print(scrapy.__file__)

(3)在虚拟环境目录中查找

通常,当你通过pip安装一个包时,它会被安装在虚拟环境的lib目录下。你可以直接查看该目录来找到Scrapy:

# 列出所有文件和文件夹

ls env/lib/pythonX.X/site-packages/ | grep scrapy

或者,在Windows上:

dir env\Lib\site-packages\ | findstr scrapy

3、选中项目,点击菜单栏处的“Run”即可

3、 Scrapy控制台调试

 切换到虚拟环境下

# 切换到项目工程下的虚拟环境env目录下
cd  D:\xx\项目名
# 激活虚拟环境
env\Scripts\activate

如果该项目没有Scrapy,则通过pip安装它:

# 切换到该项目所独有的虚拟环境目录下
cd  D:\xx\项目名\.\env\Lib\site-packages\
# 安装Scrapy
pip install Scrapy

执行 scrapy shell 命令测试

(env) PS D:\4Python\ProjectCode\FirstPythonProject\爬虫\Scrapy框架\qianmu> scrapy shell
通过Python模块查找Scrapy的安装位置:D:\4Python\ProjectCode\FirstPythonProject\爬虫\Scrapy框架\qianmu\env\Lib\site-packages\scrapy\__init__.py
2025-03-04 09:58:35 [scrapy.utils.log] INFO: Scrapy 2.12.0 started (bot: qianmu)
2025-03-04 09:58:35 [scrapy.utils.log] INFO: Versions: lxml 5.3.1.0, libxml2 2.11.7, cssselect 1.2.0, parsel 1.10.0, w3lib 2.3.1, Twisted 24.11.0, Python 3.13.0 (tags/v3.13.0:60403a5, Oct  7 2024, 09:38:07) [MSC v.1941 64 bit (AMD64)], pyOpenSSL 25.0.0 (OpenSSL 3.4.1 11 Feb 2025), cryptography 44.0.2, Platform Windows-11-10.0.22631-SP0
2025-03-04 09:58:35 [scrapy.addons] INFO: Enabled addons:
[]
2025-03-04 09:58:35 [asyncio] DEBUG: Using selector: SelectSelector
2025-03-04 09:58:35 [scrapy.utils.log] DEBUG: Using reactor: twisted.internet.asyncioreactor.AsyncioSelectorReactor
2025-03-04 09:58:35 [scrapy.utils.log] DEBUG: Using asyncio event loop: asyncio.windows_events._WindowsSelectorEventLoop
2025-03-04 09:58:35 [scrapy.utils.log] DEBUG: Using reactor: twisted.internet.asyncioreactor.AsyncioSelectorReactor
2025-03-04 09:58:35 [scrapy.utils.log] DEBUG: Using asyncio event loop: asyncio.windows_events._WindowsSelectorEventLoop
2025-03-04 09:58:35 [scrapy.extensions.telnet] INFO: Telnet Password: 0159947ba9a66546
2025-03-04 09:58:35 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.corestats.CoreStats',
 'scrapy.extensions.telnet.TelnetConsole']
2025-03-04 09:58:35 [scrapy.crawler] INFO: Overridden settings:
{'BOT_NAME': 'qianmu',
 'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter',
 'FEED_EXPORT_ENCODING': 'utf-8',
 'HTTPCACHE_ENABLED': True,
 'LOGSTATS_INTERVAL': 0,
 'NEWSPIDER_MODULE': 'qianmu.spiders',
 'ROBOTSTXT_OBEY': True,
 'SPIDER_MODULES': ['qianmu.spiders'],
 'TWISTED_REACTOR': 'twisted.internet.asyncioreactor.AsyncioSelectorReactor'}
2025-03-04 09:58:36 [scrapy.middleware] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.offsite.OffsiteMiddleware',
 'scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',
 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
 'scrapy.downloadermiddlewares.retry.RetryMiddleware',
 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',
 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware',
 'scrapy.downloadermiddlewares.stats.DownloaderStats',
 'scrapy.downloadermiddlewares.httpcache.HttpCacheMiddleware']
2025-03-04 09:58:36 [scrapy.middleware] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
 'scrapy.spidermiddlewares.referer.RefererMiddleware',
 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
 'scrapy.spidermiddlewares.depth.DepthMiddleware']
2025-03-04 09:58:36 [scrapy.middleware] INFO: Enabled item pipelines:
[]
2025-03-04 09:58:36 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
[s] Available Scrapy objects:
[s]   scrapy     scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s]   crawler    <scrapy.crawler.Crawler object at 0x000002C8A40CA120>
[s]   item       {}
[s]   settings   <scrapy.settings.Settings object at 0x000002C8A40AC690>
[s] Useful shortcuts:
[s]   fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s]   fetch(req)                  Fetch a scrapy.Request and update local objects
[s]   shelp()           Shell help (print this help)
[s]   view(response)    View response in a browser
>>>exit() # exit() 退出命令

完整创建项目以及虚拟环境命令

# 切换到项目目录下
cd D:\4Python\ProjectCode\FirstPythonProject\爬虫\Scrapy框架

# Scrapy创建项目
scrapy startproject xinpianchang

# 切换到创建的项目目录下
cd xinpianchang

# 生成spider文件;scrapy genspider [爬虫程序名称] [爬虫目标网站域名-起始url]
scrapy genspider videoartic xinpianchang.com

# 给该项目创建一个单独的虚拟环境
(.venv) PS D:\4Python\ProjectCode\FirstPythonProject\爬虫\Scrapy框架\xinpianchang> virtualenv env

# 激活虚拟环境
(.venv) PS D:\4Python\ProjectCode\FirstPythonProject\爬虫\Scrapy框架\xinpianchang> .\env\Scripts\activate

# 创建一个requirements.txt文件
(env) PS D:\4Python\ProjectCode\FirstPythonProject\爬虫\Scrapy框架\xinpianchang> pip install -r requirements.txt

# tree树形查看文件目录
tree

Scrapy shell 常用命令 

# 进入到Scrapy控制台,使用项目环境
scrapy shell

# 带一个URL参数,自动请求这个URL,并在请求成功后进入控制台
scrapy shell http://url.com


# 进入到控制台后,可使用函数和对象
fetch    请求URL或者Request对象,注:请求成功后自动将当前作用域内的Request和response对象重新赋值
view     浏览器打开response对象内的网页
shelp    打印帮助信息
spider   相应的Spider类实例
settings 保存所有配置信息的Settings对象
crawler  当前Crawler对象
Scrapy   Scrapy模块

# 项目配置下载网页,然后使用浏览器打开网页
scrapy view url 
# 项目配置下载网页,然后输出至控制台
scrapy fetch url

view命令本地下载一个网页,打开查看如下 

scrapy shell和ipython命令都可以使用,相对来说ipython更好用些

Scrapy Shell和IPython的主要区别在于它们的功能和用途

Scrapy Shell

Scrapy Shell是Scrapy框架的一个命令行工具,主要用于在爬虫开发过程中实时查看和调试网页内容。它可以在不启动爬虫的情况下,测试XPath或CSS表达式,验证提取数据的代码。Scrapy Shell提供了一个交互式终端,用户可以在其中测试和调试爬取代码,查看网页内容,并进行断言和调试‌。

IPython

IPython是一个增强的Python解释器,提供了许多高级功能,如自动缩进、语法高亮、代码补全等,使得Python编程更加便捷和高效。IPython还支持交互式并行计算、魔术命令等功能,适用于数据科学和数值计算等领域‌。

具体区别

  1. 用途‌:Scrapy Shell主要用于爬虫开发和调试,而IPython是一个通用的Python解释器增强工具,适用于各种Python编程任务。
  2. 功能‌:Scrapy Shell提供了特定的功能函数和内置对象,如fetchview等,用于获取网页响应和处理爬取数据。IPython则提供了更多的通用功能,如自动补全、魔术命令等,适用于更广泛的Python开发需求。
  3. 兼容性‌:当Scrapy Shell启动时,如果系统中安装了IPython,Scrapy Shell会优先使用IPython作为其交互式终端,提供更丰富的交互体验‌

以迁木网为例,usnews.py 

import scrapy

'''
settings.py中有一个HTTPCACHE_ENABLED配置
# 启用HTTP请求缓存,下次请求同一URL时不再发送远程请求
HTTPCACHE_ENABLED = True
'''

class UsnewsSpider(scrapy.Spider):
    name = "usnews"
    # 允许爬虫的URL必须在此字段内;genspider时可以指定;如qianmu.com意味www.qianmu.com和http.qianmu.org下的链接都可以爬取
    allowed_domains = ["www.qianmu.org"]
    # 爬虫的入口地址,可以多个
    start_urls = ["http://www.qianmu.org/2023USNEWS%E4%B8%96%E7%95%8C%E5%A4%A7%E5%AD%A6%E6%8E%92%E5%90%8D"]

    # 框架请求start_urls成功后,会调用parse方法
    def parse(self, response):
        # 提取链接,并释放
        links = response.xpath('//div[@id="content"]//tr[position()>1]/td/a/@href').extract()

        for link in links:
            if not link.startswith('http://www.qianmu.org'):
                link = 'http://www.qianmu.org/%s' % link
            # 请求成功以后,异步调用callback函数
            yield response.follow(link, self.parse_university)

    def parse_university(self, response):
        # 去除空格等特殊字符
        response = response.replace(body=response.text.replace('\t','').replace('\r\n', ''))
        data = {}
        data['name'] = response.xpath('//div[@id="wikiContent"]/h1/text()').extract_first()
        # data['name'] = response.xpath('//div[@id="wikiContent"]/h1/text()')[0]

        table = response.xpath('//div[@id="wikiContent"]//div[@class="infobox"]/table')
        if not table:
            return None
        table = table[0]
        keys = table.xpath('.//td[1]/p/text()').extract()
        cols = table.xpath('.//td[2]')
        # 当我们确定解析的数据只有1个结果时,可以使用extract_first()函数
        values = [' '.join(col.xpath('.//text()').extract()) for col in cols]
        if len(keys) == len(values):
            data.update(zip(keys, values))
        # yield出去的数据会被Scrapy框架接收,进行下一步处理;如果没有任何处理,则会打印到控制台
        yield data

参考链接

Scrapy爬虫框架详解与实践-CSDN博客

爬虫/scrapy基础入门篇_scrapy创建爬虫命令-CSDN博客

爬虫之scrapy框架 - W的一天 - 博客园

高效数据抓取:Scrapy框架详解-腾讯云开发者社区-腾讯云

Scrapy的基础使用(1) - MrSponge - 博客园

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

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

相关文章

The 2024 ICPC Kunming Invitational Contest G. Be Positive

https://codeforces.com/gym/105386/problem/G 题目&#xff1a; 结论&#xff1a; 从0开始每四个相邻数的异或值为0 代码&#xff1a; #include<bits/stdc.h> using namespace std; #define int long long void solve() {int n;cin >> n;if(n1||n%40){cout &…

GET请求如何传复杂数组参数

背景 有个历史项目&#xff0c;是GET请求&#xff0c;但是很多请求还是复杂参数&#xff0c;比如&#xff1a;参数是数组&#xff0c;且数组中每一个元素都是复杂的对象&#xff0c;这个时候怎么传参数呢&#xff1f; 看之前请求直接是拼接在url后面 类似&items%5B0%5D.…

leetcode - 双指针问题

文章目录 前言 题1 移动零&#xff1a; 思路&#xff1a; 参考代码&#xff1a; 题2 复写零&#xff1a; 思考&#xff1a; 参考代码&#xff1a; 题3 快乐数&#xff1a; 思考&#xff1a; 参考代码&#xff1a; 题4 盛最多水的容器&#xff1a; 思考&#xff1a;…

人工智能之数学基础:二次型

本文重点 二次型作为线性代数领域的重要概念,架起了代数方程与几何分析之间的桥梁。从古典解析几何中的圆锥曲线方程到现代优化理论中的目标函数,二次型以其简洁的数学表达和丰富的结构特性,在数学物理、工程技术和经济金融等领域发挥着不可替代的作用。 二次型的基本概念…

【Unity笔记】实现支持不同渲染管线的天空盒曝光度控制组件(SkyboxExposureController)——参数化控制

写在前面 在Unity中&#xff0c;天空盒&#xff08;Skybox&#xff09;不仅承担视觉上的背景作用&#xff0c;更是场景环境光照与氛围塑造的重要组成部分。不同时间、天气、场景转换等&#xff0c;都需要灵活调整天空的亮度。而**曝光度&#xff08;Exposure&#xff09;**就是…

Docker 使用与部署(超详细)

目录 引入 入门使用 部署对比 镜像仓库 命令解释 基础 常见命令 示例 数据卷的使用 数据卷的概念 数据卷的使用 挂载本地目录文件 镜像 结构 Dockerfile 容器网络 部署 DockerCompose 语法 ​编辑 基础命令 引入 当我们在 Linux 上部署一个集成了很多中间件…

CSS实现图片垂直居中方法

html <div class"footer border-top-row"><div class"footer-row"><span class"footer-row-col01">制单人&#xff1a;{{ printData[pageIndex - 1].rkMaster.makerName}}<img :src"getPersonSignImgSrc(printData[pa…

Python+Scrapy跨境电商爬虫实战:从亚马逊/沃尔玛数据采集到反爬攻克(附Pangolin API高效方案)

从零实战到反爬攻克&#xff0c;揭秘跨境数据抓取全流程与Pangolin Scrape API终极方案 在当今数据驱动的跨境电商时代&#xff0c;谁掌握了优质的市场数据&#xff0c;谁就掌握了成功的关键。随着全球电商市场规模持续扩大&#xff08;据Statista最新报告显示&#xff0c;2025…

【日撸 Java 三百行】Day 7(Java的数组与矩阵元素相加)

目录 Day 7&#xff1a;Java 的数组与矩阵元素相加 一、基本知识 二、矩阵的建立与基本计算 三、代码及测试 拓展&#xff1a;Arrays类详解 小结 Day 7&#xff1a;Java 的数组与矩阵元素相加 Task&#xff1a; 矩阵的赋值.二重循环. 一、基本知识 在学习 Java 中的数组与矩…

【Python】常用命令提示符

Python常用的命令提示符 一、Python环境基础命令【Windows】 于Windows环境下&#xff0c;针对Python&#xff0c;在CMD&#xff08;命令提示符&#xff09;常用的命令以及具体用法&#xff0c;怎么用&#xff1b;   主要包含&#xff1a;运行脚本、包管理、虚拟环境、调试与…

vite:npm 安装 pdfjs-dist , PDF.js View 预览功能示例

pdfjs-dist 是 Mozilla 的 PDF.js 库的预构建版本&#xff0c;能让你在项目里展示 PDF 文件。下面为你介绍如何用 npm 安装 pdfjs-dist 并应用 pdf.js 和 pdf.worker.js。 为了方便&#xff0c;我将使用 vite 搭建一个原生 js 项目。 1.创建项目 npm create vitelatest pdf-v…

【开源版】likeshop上门家政系统PHP版全开源+uniapp前端

一.系统介绍 likeshop_上门家政系统&#xff0c;PHP版本更新至2.1.1最新版&#xff0c;全开源&#xff0c;适用于上门家政场景&#xff0c;系统拥有用户端、师傅端、无论运营还是二开都是性价比极高的100%开源家政系统。 二.搭建环境-教程 系统环境&#xff1a;CentOS、 运行…

MySQL 8.0 OCP 英文题库解析(一)

Oracle 为庆祝 MySQL 30 周年&#xff0c;从 2025.04.20 ~ 2025.07.31 之间&#xff0c;所有人均可以免费考取 MySQL OCP 认证。从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证&#xff0c;省1700多RMB&…

路由器断流排查终极指南:从Ping测试到Wireshark抓包5步定位法

测试路由器是否出现“断流”&#xff08;网络连接间歇性中断&#xff09;&#xff0c;需通过多维度排查硬件、软件及外部干扰因素。以下是详细步骤指南&#xff1a; 一、基础环境准备 设备连接 有线测试&#xff1a;用网线将电脑直接连接路由器LAN口&#xff0c;排除WiFi干扰。…

04 基于 STM32 的时钟展示程序

前言 我们经常会看到 各个场合下面有 基于数码管 的时钟程序 比如 在车站, 教室, 办公室 等等 各个场合都有 然后 这里就是做一个 简单的 时钟程序 展示程序 测试用例 每一秒钟更新时间, 然后 迭代更新 天, 时, 分 等等 然后 主流程 基于 天, 时分秒 渲染数码管 #incl…

n8n工作流自动化平台:生成图文并茂的分析报告之Merge节点详细说明

1.成果展示 1.1工作流示意图 1.2成果 数据都是造得 2Merge节点 2.1Mode 通过选择模式指定合并节点应如何组合来自不同数据流的数据 2.1.1Append 保存所有输入的数据。选择一个输入数量,逐一输出每个输入的项目。节点等待所有连接的输入的执行。 2.1.2Combine 2.1.2.1Co…

华为设备MSTP

一、MSTP核心理论 1. 基本概念 MSTP定义&#xff1a;MSTP&#xff08;Multiple Spanning Tree Protocol&#xff09;是一种基于实例的生成树协议&#xff0c;支持多个生成树实例&#xff08;MSTI&#xff09;&#xff0c;每个实例对应一组VLAN&#xff0c;实现不同VLAN流量的负…

Loly: 1靶场渗透

Loly: 1 来自 <Loly: 1 ~ VulnHub> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182&#xff0c;靶场IP192.168.23.241 3&#xff0c;对靶机进行端口服务探测 n…

Linux系统入门第十一章 --Shell编程之函数与数组

一、Shell函数 1、函数的用法 Shell函数可用于存放一系列的指令。在Shell脚本执行的过程中&#xff0c;函数被置于内存中&#xff0c;每次调用函数时不需要从硬盘读取&#xff0c;因此运行的速度比较快。在Shell编程中函数并非是必须的元素&#xff0c;但使用函数可以对程序进…

聊聊自动化办公未来趋势

1. 自动化办公未来趋势 1.1 智能化与AI融合加深 随着人工智能技术的不断成熟&#xff0c;其在自动化办公中的应用将更加广泛和深入。未来&#xff0c;办公软件将具备更强的智能交互能力&#xff0c;能够理解自然语言指令&#xff0c;自动完成复杂的任务&#xff0c;如文档编辑…