爬虫 Scrapy 学习系列之一:Tutorial

Scrapy 一个强大的基于Python的开源爬虫框架 Scrapy tutorial: Learning web scraping using Python Scrapy是一个强大的基于Python的开源爬虫框架,它可以用来抓取网页数据,进行数据提取、分析及存储等任务。本教程旨在带领大家了解如何使用Scrapy框架来进行网页数据采集。Scrapy框架支持多种编程语言,包括Python,C++,Java,Ruby和PHP,并提供了完整的官方API文档。它提供了强大的管道系统,允许用户自定义数据处理流程。通过可扩展的spider组件和部署方案,Scrapy也能够快速抓取大量数据。如何安装Scrapy环境;基本的Scrapy命令行用法; 阅读详情

前言

笔者打算写一系列的文章,记录自己在学习并使用 Scrapy 的点滴;作者打算使用 python 3.6 作为 Scrapy 的基础运行环境;

本文为作者的原创作品,转载需注明出处;

备注:本文转载自本人的博客,伤神的博客:http://www.shangyang.me/2017/06/29/scrapy-learning-1-tutorial/

Scrapy 安装

我本地安装有两个版本的 python, 2.7 和 3.6;而正如前言所描述的那样,笔者打算使用 Python 3.6 的环境来搭建 Scrapy;

     
1
     
$ pip install Scrapy

默认安装的支持 Python 2.7 版本的 Scrapy;

     
1
     
$ pip3 install Scrap

安装的是支持 python 3.x 版本的 Scrapy;不过安装过程中,遇到了些问题,HTTPSConnectionPool(host=’pypi.python.org’, port=443): Read timed out.解决办法是,在安装的过程中,延长超时的时间,

     
1
     
$ pip3 install -U --timeout 1000 Scrapy

Scrapy Tutorial

创建 tutorial 项目

使用

     
1
2
3
     
$ scrapy startproject tutorial
New Scrapy project 'tutorial', using template directory '/usr/local/lib/python2.7/site-packages/scrapy/templates/project', created in:
/Users/mac/workspace/scrapy/tutorial

可见默认使用的 python 2.7,但是如果需要创建一个支持 python 3.x 版本的 tutoiral 项目呢?如下所示,使用 python3 -m

     
1
2
3
     
$ python3 -m scrapy startproject tutorial
New Scrapy project 'tutorial', using template directory '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/scrapy/templates/project', created in:
/Users/mac/workspace/scrapy/tutorial

导入 PyCharm

直接 open 项目工程 /Users/mac/workspace/scrapy/tutorial;这里需要注意的是默认的 PyCharm 使用的解释器 Interpretor 是我本地的 Python 2.7;这里需要将解释器改为 Python 3.6;下面记录下修改的步骤,

  1. 点击左上角 PyCharm Community Edition,进入 Preferences
  2. 点击 Project:tutorial,然后选择 Project Interpreter,然后设置解释器的版本,如下

工程结构

通过命令构建出来的项目骨架如图所示

第一个 Spider

我们来新建一个 Spider 类,名叫 quotes_spider.py,并将其放置到 tutorial/spiders 目录中

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
     
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
def start_requests(self):
urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
for url in urls:
yield scrapy.Request(url=url, callback=self.parse)
def parse(self, response):
page = response.url.split( "/")[ -2]
filename = 'quotes-%s.html' % page
with open(filename, 'wb') as f:
f.write(response.body)
self.log( 'Saved file %s' % filename)

可以看到,我们新建的 QuotesSpider 类是继承自 scrapy.Spider 类的;下面看看其属性和方法的意义,

  • name
    是 Spider 的标识符,用于唯一标识该 Spider;它必须在整个项目中是全局唯一的;
  • start_requests()
    必须定义并返回一组可以被 Spider 爬取的 Requests,Request 对象由一个 URL 和一个回调函数构成;
  • parse()
    就是 Request 对象中的回调方法,用来解析每一个 Request 之后的 Response;所以,parse() 方法就是用来解析返回的内容,通过解析得到的 URL 同样可以创建对应的 Requests 进而继续爬取;

再来看看具体的实现,

  • start_request(self) 方法分别针对 http://quotes.toscrape.com/page/1/ 和 http://quotes.toscrape.com/page/2/ 创建了两个需要被爬取的 Requests 对象;并通过 yield 进行迭代返回;备注,yield 是迭代生成器,是一个 Generator;
  • parse(self, response) 方法既是对 Request 的反馈的内容 Response 进行解析,这里的解析的逻辑很简单,就是分别创建两个本地文件,然后将 response.body 的内容放入这两个文件当中。

如何执行

执行的过程需要使用到命令行,注意,这里需要使用到scrapy命令来执行;

     
1
2
     
$ cd /Users/mac/workspace/scrapy/tutorial
$ python3 -m scrapy crawl quotes

大致会输出如下内容

     
1
2
3
4
5
6
7
8
9
10
11
     
...
2016-12-16 21:24:05 [scrapy.core.engine] INFO: Spider opened
2016-12-16 21:24:05 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2016-12-16 21:24:05 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023
2016-12-16 21:24:05 [scrapy.core.engine] DEBUG: Crawled (404) <GET http://quotes.toscrape.com/robots.txt> (referer: None)
2016-12-16 21:24:05 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/1/> (referer: None)
2016-12-16 21:24:05 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/2/> (referer: None)
2016-12-16 21:24:05 [quotes] DEBUG: Saved file quotes-1.html
2016-12-16 21:24:05 [quotes] DEBUG: Saved file quotes-2.html
2016-12-16 21:24:05 [scrapy.core.engine] INFO: Closing spider (finished)
...

可以看到,通过爬取,我们在本地生成了两个 html 文件 quotes-1.html 和 quotes-2.html

如何提取

通过命令行的方式提取

Scrapy 提供了命令行的方式可以对需要被爬取的内容进行高效的调试,通过使用Scrapy shell进入命令行,然后在命令行中可以快速的对要爬取的内容进行提取;

如何进入 Scrapy shell 环境

我们试着通过 Scrapy shell 来提取下 “http://quotes.toscrape.com/page/1/“ 中的数据,通过执行如下命令,进入 shell

     
1
     
$ scrapy shell "http://quotes.toscrape.com/page/1/"

输出

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     
[ ... Scrapy log here ... ]
2016-09-19 12:09:27 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/page/1/> (referer: None)
[s] Available Scrapy objects:
[s] scrapy scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s] crawler <scrapy.crawler.Crawler object at 0x7fa91d888c90>
[s] item {}
[s] request <GET http://quotes.toscrape.com/page/1/>
[s] response <200 http://quotes.toscrape.com/page/1/>
[s] settings <scrapy.settings.Settings object at 0x7fa91d888c10>
[s] spider <DefaultSpider 'default' at 0x7fa91c8af990>
[s] Useful shortcuts:
[s] shelp() Shell help ( print this help)
[s] fetch(req_or_url) Fetch request (or URL) and update local objects
[s] view(response) View response in a browser
>>>

这样,我们就进入了 Scrapy shell 的环境,上面显示了连接请求和返回的相关信息,response 返回 status code 200 表示成功返回;

通过 CSS 标准进行提取

这里主要是遵循 CSS 标准 https://www.w3.org/TR/selectors/ 来对网页的元素进行提取,

  1. 通过使用 css() 选择我们要提取的元素;下面演示一下如何提取元素 <title/>

           
    1
    2
           
    >>> response.css( 'title')
    [<Selector xpath=u 'descendant-or-self::title' data=u '<title>Quotes to Scrape</title>'>]

    可以看到,它通过返回一个类似 SelectorList 的对象成功的获取到了 http://quotes.toscrape.com/page/1/ 页面中的 <title/> 的信息,该信息是封装在Selector对象中的 data 属性中的;

  2. 提取Selector元素的文本内容,一般有两种方式用来提取,

    • 通过使用 extract() 或者 extract_first() 方法来提取元素的内容;下面演示如何提取 #1 返回的元素 <title/> 中的文本内容 text;

               
      1
      2
               
      >>> response.css( 'title::text').extract_first()
      'Quotes to Scrape'

      extract_first() 表示提取返回队列中的第一个 Selector 对象;同样也可以使用如下的方式,

               
      1
      2
               
      >>> response.css( 'title::text')[0].extract()
      'Quotes to Scrape'

      不过 extract_first() 方法可以在当页面没有找到的情况下,避免出现IndexError的错误;

    • 通过 re() 方法来使用正则表达式的方式来进行提取元素的文本内容

               
      1
      2
      3
      4
      5
      6
               
      >>> response.css( 'title::text').re(r 'Quotes.*')
      [ 'Quotes to Scrape']
      >>> response.css( 'title::text').re(r 'Q\w+')
      [ 'Quotes']
      >>> response.css( 'title::text').re(r '(\w+) to (\w+)')
      [ 'Quotes', 'Scrape']

      备注,最后一个正则表示式返回了两个匹配的 Group;

使用 XPath

除了使用 CSS 标准来提取元素意外,我们还可以使用 XPath 标准来提取元素,比如,

     
1
2
3
4
     
>>> response.xpath( '//title')
[<Selector xpath= '//title' data= '<title>Quotes to Scrape</title>'>]
>>> response.xpath( '//title/text()').extract_first()
'Quotes to Scrape'

XPath 比 CSS 的爬取方式更为强大,因为它不仅仅是根据 HTML 的结构元素去进行检索(Navigating),并且它可以顺带的对文本(text)进行检索;所以它可以支持 CSS 标准不能做到的场景,比如,检索一个 包含文本内容”Next Page”的 link 元素;这就使得通过 XPath 去构建爬虫更为简单;

提取 quotes 和 authors

下面我们将来演示如何提取 http://quotes.toscrape.com 首页中的内容,先来看看首页的结构

可以看到,里面每个段落包含了一个名人的一段语录,那么我们如何来提取所有的相关信息呢?

我们从提取第一个名人的信息入手,看看如何提取第一个名人的名言信息;可以看到,第一个名人的语句是爱因斯坦的,那么我们试着来提取名言、作者以及相关的tags;

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     
<div class="quote">
<span class="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">Albert Einstein </small>
<a href="/author/Albert-Einstein">(about) </a>
</span>
<div class="tags">
Tags:
<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>

下面我们就来试着一步一步的去提取相关的信息,

首先,进入 Scrapy Shell,

     
1
     
$ scrapy shell 'http://quotes.toscrape.com'

然后,获取 <div class="quote" /> 元素列表

     
1
     
>>> response.css( "div.quote")

这里会返回一系列的相关的 Selectors,不过因为这里我们仅仅是对第一个名言进行解析,所以我们只取第一个元素,并将其保存在 quote 变量中

     
1
     
>>> quote = response.css( "div.quote")[0]

然后,我们来分别提取title、author和tags

  1. 提取title

           
    1
    2
    3
           
    >>> title = quote.css( "span.text::text").extract_first()
    >>> title
    '“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”'
  2. 提取author

           
    1
    2
    3
           
    >>> author = quote.css( "small.author::text").extract_first()
    >>> author
    'Albert Einstein'
  3. 提取tags,这里需要注意的是,tags 是一系列的文本,

           
    1
    2
    3
           
    >>> tags = quote.css( "div.tags a.tag::text").extract()
    >>> tags
    [ 'change', 'deep-thoughts', 'thinking', 'world']

Ok,上述完成了针对其中一个名言信息的提取,那么,我们如何提取完所有名人的名言信息呢?

     
1
2
3
4
5
6
7
8
     
>>> for quote in response.css( "div.quote"):
... text = quote.css( "span.text::text").extract_first()
... author = quote.css( "small.author::text").extract_first()
... tags = quote.css( "div.tags a.tag::text").extract()
... print(dict(text=text, author=author, tags=tags))
{ 'tags': [ 'change', 'deep-thoughts', 'thinking', 'world'], 'author': 'Albert Einstein', 'text': '“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”'}
{ 'tags': [ 'abilities', 'choices'], 'author': 'J.K. Rowling', 'text': '“It is our choices, Harry, that show what we truly are, far more than our abilities.”'}
... a few more of these, omitted for brevity

写个循环,将所有的信息的信息放入 Python dictionary;

通过 Python 程序来进行提取

本小计继续沿用提取 quotes 和 authors 小节的例子,来看看如何通过 python 程序来做相同的爬取动作;

提取数据

修改该之前的 quotes_spider.py 内容,如下,

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
     
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
'http://quotes.toscrape.com/page/2/',
]
def parse(self, response):
for quote in response.css( 'div.quote'):
yield {
'text': quote.css( 'span.text::text').extract_first(),
'author': quote.css( 'small.author::text').extract_first(),
'tags': quote.css( 'div.tags a.tag::text').extract(),
}

执行上述的名为 quotes 的爬虫,

     
1
     
$ scrapy crawl quotes

执行结果如下,

     
1
2
3
4
     
2016-09-19 18:57:19 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.toscrape.com/page/1/>
{ 'tags': [ 'life', 'love'], 'author': 'André Gide', 'text': '“It is better to be hated for what you are than to be loved for what you are not.”'}
2016-09-19 18:57:19 [scrapy.core.scraper] DEBUG: Scraped from <200 http://quotes.toscrape.com/page/1/>
{ 'tags': [ 'edison', 'failure', 'inspirational', 'paraphrased'], 'author': 'Thomas A. Edison', 'text': "“I have not failed. I've just found 10,000 ways that won't work.”"}

可以看到,我们通过 python 创建的爬虫 quotes 一条一条的返回了爬取的信息;

保存数据

最简单保存方式被爬取的数据是通过使用 Feed exports,通过使用如下的命令,

使用 JSON 格式
     
1
     
$ scrapy crawl quotes -o quotes.json

上述命令会生成一个文件quotes.json,该文件中包含了所有被爬取的数据;不过由于历史的原因,Scrapy 是往一个文件中追加被爬取的信息,而不是覆盖更新,所以如果你执行上述命令两次,将会得到一个损坏了的 json 文件;

使用 JSON Lines 格式
     
1
     
$ scrapy crawl quotes -o quotes.jl

这样,保存的文件就是 JSON Lines 的格式了,注意,这里的唯一变化是文件的后缀名改为了.jl;

补充,JSON Lines 是另一种 JSON 格式的定义,基本设计是每行是一个有效的 JSON Value;比如它的格式比 CSV 格式更友好,

     
1
2
3
4
5
     
[ "Name", "Session", "Score", "Completed"]
[ "Gilbert", "2013", 24, true]
[ "Alexa", "2013", 29, true]
[ "May", "2012B", 14, false]
[ "Deloise", "2012A", 19, true]

同时也可以支持内嵌数据,

     
1
2
3
4
     
{ "name": "Gilbert", "wins": [[ "straight", "7♣"], [ "one pair", "10♥"]]}
{ "name": "Alexa", "wins": [[ "two pair", "4♠"], [ "two pair", "9♠"]]}
{ "name": "May", "wins": []}
{ "name": "Deloise", "wins": [[ "three of a kind", "5♣"]]}

JSON Lines 格式非常适合处理含有大量数据的文件,通过迭代,每行处理一个数据对象;不过,要注意的是,使用 JSON lines 的方式,Scrapy 同样的是以追加的方式添加内容,只是因为 JSON Lines 逐行的方式添加被爬取的数据,所以以追加的方式并不会想使用 JSON 格式那样导致文件格式错误;

如果是一个小型的项目,使用 JSON Lines 的方式就足够了;但是,如果你面临的是一个更复杂的项目,而且有更复杂的数据需要爬取,那么你就可以使用 Item Pipeline;一个 demo Pipelines 已经帮你创建好了,tutorial/pipelines.py;

提取下一页(提取链接信息)

如何提取章节详细的描述了如何爬取页面的信息,那么,如何爬取该网站的所有信息呢?那么就必须爬取相关的链接信息;那么我们依然以 http://quotes.toscrape.com 为例,来看看我们该如何爬取链接信息,

我们可以看到,下一页的链接 HTML 元素,

     
1
2
3
4
5
     
<ul class="pager">
<li class="next">
<a href="/page/2/">Next <span aria-hidden="true">&rarr; </span> </a>
</li>
</ul>

我们可以通过 shell 来抓取它,

     
1
2
     
>>> response.css( 'li.next a').extract_first()
'<a href="/page/2/">Next <span aria-hidden="true">→</span></a>'

这样,我们得到了这个anchor元素,但是我们想要得到的是其href属性;Scrapy 支持 CSS 扩展的方式,因此我们可以直接爬取其属性值,

     
1
2
     
>>> response.css( 'li.next a::attr(href)').extract_first()
'/page/2/'

好的,我们现在已经知道该如何获取下一页链接的相对地址了,那么我们如何修改我们的 python 程序使得我们可以自动的爬取所有页面的数据呢?

使用 scrapy.Request
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
     
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
]
def parse(self, response):
for quote in response.css( 'div.quote'):
yield {
'text': quote.css( 'span.text::text').extract_first(),
'author': quote.css( 'small.author::text').extract_first(),
'tags': quote.css( 'div.tags a.tag::text').extract(),
}
next_page = response.css( 'li.next a::attr(href)').extract_first()
if next_page is not None:
next_page = response.urljoin(next_page)
yield scrapy.Request(next_page, callback=self.parse)

这里简单的描述下程序的执行逻辑,通过 for 循环处理完当前页面的爬取操作,然后执行获取下一页的相关操作,首先获得下一页的相对路径并保存到变量 next_page 中,然后通过 response.urljon(next_page) 方法得到绝对路径;最后,通过该绝对路径再生成一个 scrapy.Request 对象返回,并加入 爬虫队列中,等待下一次的爬取;由此,你就可以动态的去爬取所有相关页面的信息了;

基于此,你就可以建立起非常复杂的爬虫了,同样,可以根据不同链接的类型,构建不同的 Parser,那么就可以对不同类型的返回页面进行分别处理;

使用 response.follow

不同于使用 scrapy Request,需要通过相对路径构造出绝对路径,response.follow 可以直接使用相对路径,因此就不需要调用 urljoin 方法了;注意,response.follow 直接返回一个 Request 实例,可以直接通过 yield 进行返回;所以,上述代码可以简化为

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
     
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/page/1/',
]
def parse(self, response):
for quote in response.css( 'div.quote'):
yield {
'text': quote.css( 'span.text::text').extract_first(),
'author': quote.css( 'span small::text').extract_first(),
'tags': quote.css( 'div.tags a.tag::text').extract(),
}
next_page = response.css( 'li.next a::attr(href)').extract_first()
if next_page is not None:
yield response.follow(next_page, callback=self.parse)

另外,response.follow 在处理 <a> 元素的时候,会直接使用它们的 href 属性;所以上述代码还可以简化为,

     
1
2
3
     
next_page = response.css( 'li.next a').extract_first()
if next_page is not None:
yield response.follow(next_page, callback=self.parse)

因此匹配的时候不需要显示的声明 <a> 的属性值了;

定义更多的 Parser

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
     
import scrapy
class AuthorSpider(scrapy.Spider):
name = 'author'
start_urls = [ 'http://quotes.toscrape.com/']
def parse(self, response):
# follow links to author pages
for href in response.css( '.author + a::attr(href)'):
yield response.follow(href, self.parse_author)
# follow pagination links
for href in response.css( 'li.next a::attr(href)'):
yield response.follow(href, self.parse)
def parse_author(self, response):
def extract_with_css(query):
return response.css(query).extract_first().strip()
yield {
'name': extract_with_css( 'h3.author-title::text'),
'birthdate': extract_with_css( '.author-born-date::text'),
'bio': extract_with_css( '.author-description::text'),
}

该例子创建了两个解析方法 parse() 和 parse_author(),一个是用来控制整个爬取流程,一个是用来解析 author 信息的;首先,我们来分析一下执行的流程,

  1. 进入 parse(),从当前的页面中爬取得到所有相关的 author href 属性值既是一个链接,然后针对该链接,通过 response.follow 创建一个新的 Request 继续进行爬取,通过回调 parse_author() 方法对爬取的内容进行进一步的解析,这里就是对爬取到的 Author 的信息进行提取;

  2. 当 #1 有关当前页面所有的 Author 信息都已经爬取成功以后,便开始对下一页进行爬取;

从这个例子中,我们需要注意的是,当爬取当前页面的时候,我们依然可以通过创建子的 Requests 对子链接进行爬取直到所有有关当前页面的信息都已经被爬取完毕以后,方可进入下一个页面继续进行爬取;

另外,需要注意的是,在爬取整个网站信息的时候,必然会有多个相同 Author 的名言,那么势必要爬取到许多的重复的 Author 的信息;这无疑是增加了爬取的压力同时也需要处理大量的冗余数据,基于此,Scrapy 默认实现了对重复的已经爬取过的链接在下次爬取的时候自动过滤掉了;不过,你也可以通过 DUPEFILTER_CLASS 来进行设置是否启用该默认行为;

使用 Spider 参数

你可以通过 commond line 的方式为你的 Spider 提供参数,

     
1
     
$ scrapy crawl quotes -o quotes-humor.json -a tag=humor

该参数将会被传入 Spider 的 __init__ 方法中,并默认成为当前 Spider quotes 的属性;在 quotes Spider 的 python 应用程序中,可以通过使用 self.tag 来获取该参数信息;

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
     
import scrapy
class QuotesSpider(scrapy.Spider):
name = "quotes"
def start_requests(self):
url = 'http://quotes.toscrape.com/'
tag = getattr(self, 'tag', None)
if tag is not None:
url = url + 'tag/' + tag
yield scrapy.Request(url, self.parse)
def parse(self, response):
for quote in response.css( 'div.quote'):
yield {
'text': quote.css( 'span.text::text').extract_first(),
'author': quote.css( 'small.author::text').extract_first(),
}
next_page = response.css( 'li.next a::attr(href)').extract_first()
if next_page is not None:
yield response.follow(next_page, self.parse)

通过 getattr(self, 'tag', None) 便可以获取从 common line 中传入的 tag 参数,并构造出需要爬取的 URL 链接 http://quotes.toscrape.com/tag/humor

Reference

Scrapy 爬虫框架:http://python.jobbole.com/86405/
Installation Guide: https://doc.scrapy.org/en/latest/intro/install.html
explain how virtualenv used: https://stackoverflow.com/questions/41151141/how-to-get-scrapy-to-use-python-3-when-both-python-versions-are-installed
tutorial guide: https://doc.scrapy.org/en/latest/intro/tutorial.html
Scrapy Clusters: http://scrapy-cluster.readthedocs.io/en/latest/
Scrapy Deployment: https://scrapyd.readthedocs.io/en/latest/deploy.html
Scrapy 0.24 文档:http://scrapy-chs.readthedocs.io/zh_CN/0.24/index.html

scrapy入门例子-tutorial 博文代码附件。详情请访问博文《Eclipse集成Scrapy配置调试》 http://blog.youkuaiyun.com/otengyue/article/details/48065841 立即下载

相关推荐

MCGS触摸屏数据记录与U盘导出配置全解析

在工业自动化现场,数据记录是设备运行状态分析与故障追溯的基础。HMI触摸屏作为人机交互核心,不仅承担实时监控任务,还负责过程数据的存储与导出。理解数据采集周期、存盘机制与存储介质的匹配原理,能帮助工程师高效配置数据记录功能。合理运用定时存盘、存盘组与U盘导出,可支撑设备趋势分析、报表生成及事故排查。本文以MCGS触摸屏为例,详解数据记录的完整组态流程,并汇总常见配置陷阱与排查思路,为现场调试与长期运维提供可落地的技术参考。

weixin_34253126的博客 459

Python爬虫进阶(八):Scrapy Tutorial

Tutorial意为“教程”、“使用说明书”,但本文其实并不能完全地达到这个目的。相比于scrapy完善的doc,本文仅旨在给读者一个基础的关于scrapy的印象,并且为接下来的实例教程打下基础。关于scrapy框架的更深入的学习,还请读者自己努力了。 PS:本节的大部分参考资料来自scrapy官方文档。希望能有英语好的大神翻个中文版,目前网上流传的机翻版本基本上只能起到个聊胜于无的作用。 spiders/spider.py(爬虫文件) 在上一节中我们创建了一个scrapy项目start01,并为其创

AugustTheodor的博客 633

c语言实现语音检测vad_壹鸽技术科普·智能语音客服系统中的前端语音处理技术...

随着智能客服机器人产业的迅速发展,尤其是伴随着人工智能AI的风潮,预计在2020年我国智能客服市场将达到万亿级别。在智能客服机器人领域中对电话信道语音进行端点检测处理的应用正在不断扩展和深化。目前语音端点检测(Voice Active Detection,简称VAD)的主要任务是准确快速判决出待处理的语音信号有话还是无话,作为自动语音识别(Automatic Speech Recognition,...

weixin_36431018的博客 508

Python爬虫采集框架——Scrapy初学入门

scrapy.Request支持绝对URL,而response.follow支持相对URL,并返回一个请求实例。只需定义start_urls属性,不需重写start_requests() 方法,由默认的start_requests()方法根据start_urls属性开始请求也可。该蜘蛛将提取页面中的text、author和tags,使用终端打印,提取下一页的地址并开始请求,以此递归。蜘蛛开始请求(方法返回的是请求的iterable)

激情人生,美好生活 1608

图解基站机房:AAU、RRU与BBU之间的线缆连接与规格选择

本文以图解方式详解了5G基站机房中AAU、RRU与BBU三大核心设备之间的线缆连接方案与规格选择。重点阐述了电力线(如2×10 mm²直流电缆)、数据光缆(如野战光缆与波分复用)及射频馈线的功能、选型标准与实战布线法则,为通信工程部署与维护提供清晰指导。

weixin_29306011的博客 499

IDEA类和方法注释模板设置(非常详细)

IDEA类和方法注释模板设置(非常详细)

黑桃A的博客 10万+

Scrapy学习记录

目录 Scrapy框架的使用 Scrapy入门 1.本节目标 2.准备工作 3.创建项目 4.创建Spider 5.创建Item 6.解析Response 7.使用Item 8.后续Request Scrapy框架的使用 Scrapy入门 1.本节目标 创建一个Scrapy项目 编写一个Spider来抓取站点和处理数据 初步了解Item Pipeline的功能,将抓取的内容保存 运行Scrapy爬虫项目 要抓取的目标站点: Quotes

小刘的博客 525

用miniconda建立PyTorch、Keras、TensorFlow三个环境

如果还没有安装Miniconda,请从[Miniconda官网](https://docs.conda.io/en/latest/miniconda.html)下载合适的版本并进行安装。如果遇到问题,可以通过编辑`~/.condarc`文件来临时禁用某个源,或者通过`conda config --remove channels`命令来移除配置的镜像源。要切换到不同的环境,先使用`conda deactivate`命令退出当前环境,再用`conda activate 环境名称`命令激活另一个环境。

数字人生 2464

python 爬虫(六) scrapy tutorial 1

今天开始scrapy的学习,环境 ubuntu 16.04 python3.5 1. 创建scrapy爬虫工程 通过终端进入要放置爬虫的文件夹,在我的环境中~/PycharmProjects/ScrapyWord/tutorial 使用命令:scrapy startproject tutorial 会创建tutorial文件夹,在这个文件夹下面会包...

donggangzuan7209的博客 205

华为OD机试 - 最佳对手(Python/JS/C/C++ 2025 A卷 200分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。游戏里面,队伍通过匹配实力相近的对手进行对战。但是如果匹配的队伍实力相差太大,对于双方游戏体验都不会太好。给定n个队伍的实力值,对其进行两两实力匹配,两支队伍实例差距在允许的最大差距d内,则可以匹配。要求在匹配队伍最多的情况下,匹配出的各组实力差

学Java,找哪吒 1379

第201期 解锁科研效率新高度:Claude 科学技能插件(claude-scientific-skills)深度体验

科研AI助手Claude Scientific Skills开源工具为Claude大模型扩展科学能力,覆盖数据可视化、数学计算、学术格式处理等科研全流程需求。该插件支持LaTeX公式生成、自动化科研图表绘制、学术文档规范校正等功能,让研究人员通过自然语言指令即可完成专业任务。项目开源可定制,支持特定学科需求扩展,目前已托管于GitHub。使用门槛低,只需配置Claude API密钥即可快速启用,帮助科研人员从繁琐技术细节中解放,聚焦核心研究创新。

全网120W+关注AI拉呱,专注人工智能以及科技前沿! 1358

scrapy简单项目使用

1、首先安装scrpay--不多说基本功 2、新建一个爬虫项目 scrapy startproject scrapy_tutorial 3、新建之后的目录结构不多说,进入到项目 cd scrapy_tutorial  新建一个示例使用 scrapy genspider dmoz_spider dmoz.org 此时目录结构如图所示 4、编写spider,spider为 5、item是

优快云你大爷的的专栏 812

Windows 下 Codex 安装全记录:从零到一的保姆级图文教程

本文主要介绍了Windows 下 Codex 安装全记录:从零到一的保姆级图文教程,希望能对学习使用 Codex 的同学们有所帮助。 文章目录 1. 背景 2. 实战教程 2.1 方案一 2.2 方案二 3. 报错解决方案

weixin_43178406的博客 14万+

Scrapy框架深度解析:Easy-scraping-tutorial企业级爬虫开发指南

想要掌握Python网络爬虫的终极技能吗?Scrapy框架无疑是你的最佳选择!本文将基于easy-scraping-tutorial项目,为你提供一份完整的Scrapy企业级爬虫开发指南。无论你是Python爬虫新手,还是希望提升到专业水平的开发者,这份教程都将帮助你快速掌握Scrapy框架的核心技术。🚀 ## 为什么选择Scrapy框架? Scrapy是一个功能强大的Python网络爬虫框

gitblog_00334的博客 794

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Jupyter Notebook学习路径:Easy-scraping-tutorial交互式爬虫教程

想要快速掌握Python网络爬虫技术吗?easy-scraping-tutorial项目提供了一个完美的交互式学习路径,通过Jupyter Notebook让你从零开始构建实用的网络爬虫。这个教程采用循序渐进的方式,从最简单的网页读取到高级的Selenium和Scrapy框架,让你在实战中掌握爬虫技能。 ## 🚀 为什么选择Jupyter Notebook学习爬虫? Jupyter Note

gitblog_00764的博客 659

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

爬虫框架:Scrapy 快速入门

文章目录一、Scrapy简介1.1 示例代码1.2 示例代码的运行流程二、安装Scrapy2.1 Ubuntu下安装2.2 Windows下安装2.3 Mac OS下安装三、Scrapy 快速入门3.1 创建 scrapy 项目3.2 编写 spider3.3 运行爬虫项目3.3.1 start_requests 方法的快捷方式3.4 数据提取3.4.1 提取名言和作者3.4.2 在 spider 中提取数据3.5 存储提取的数据3.6 追踪链接3.7 创建请求的快捷方式3.8 更多示例和模式3.9 使用

花城的博客 3234

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【爬虫——00001】favorite scrapy tutorial

Declaration : 以下代码测试过没有问题,时间点20200603*** create project scrapy startproject tutorial **创建的项目 目录包含以下内容:**在做A时可以把文件目录放到问题里,看是否能说出每个文件是做什么的? 我的第一只小蜘蛛 quotes_spider.py 下 tutorial/spiders 项目中的目录: import scrapy class QuotesSpider(scrapy.Spider): name = ".

玉 184

如何快速入门Python爬虫:Easy-scraping-tutorial基础教程

想要快速掌握Python爬虫技术?Easy-scraping-tutorial项目为你提供了一套完整而简单的Python网络爬虫教程代码。这个开源项目通过实际案例和循序渐进的教学方式,帮助初学者轻松入门网页数据抓取技术。无论你是数据分析师、研究人员还是开发者,学习Python爬虫都能让你从海量网页中高效提取有价值的信息。🚀 ## 📚 什么是Python爬虫? Python爬虫是一种自动化程

gitblog_00709的博客 1061

Scrapy爬虫框架学习一

Scrapy爬虫框架学习(一) 官方文档给出的例子爬取的网址失效,加上语法版本问题导致一些功能无法实现,我自己修正了一下,以让后人事倍功半,避免空耗时间。 正文 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。 Scrapy安装只需要pip install scrapy即可 创建一个scrapy项目 #在pyth...

mostermoonsky的博客 359

Scrapy Tutorial

设置。

m0_56086190的博客 1060

scrapy爬虫折腾系列-02

Scrapy折腾系列-02 1、笔记 response是一个scrapy.http.response.html.HtmlResponse对象,可执行xpath和css语法来提取数据 提取出来的数据,是一个 Selector或者是一个selectorList对象,要想获取其中的字符串,得执行getall或者get方法 getall方法:获取selector中的所有文本,返回的是一个列表 get方法...

juntech.top 830

Scrapy学习过程之三:tutorial

参考:tutorial 贴出架构架构图以便参考: 本tutorial涉及到的内容: 创建一个scrapy工程 写一个spider爬网页并提取数据 使用命令行导出scrapy数据 将spider改成递归跟踪链接 给spider传递参数 Creating a project 自己先创建一个目录,然后运行如下命令: scrapy startproject tutorial 此命...

山不转的博客 443

python爬虫框架scrapy学习笔记

介绍:scrapy是一个python的爬虫框架 官方英文文档比较完整 支持web2.0 官方文档:doc.scrapy.org 本机环境:ubuntu 12.04 安装命令: sudo easy_install python-twisted sudo easy_install w3lib sudo easy_install lxml sudo easy_install pyopenss

贱贱的刁民的技术博客 8165
上一篇: android 备忘
下一篇: Spring Core Container 源码分析三:Spring Beans 初始化流程分析
伤神v
博客等级 码龄19年 17粉丝 129原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值