Scrapy-spiders(爬虫)

 

Scrapy Spiders(中文版):http://doc.scrapy.org/en/latest/topics/spiders.html

Scrapy Spiders(中文版):https://scrapy-chs.readthedocs.io/zh_CN/latest/topics/spiders.html

Scrapy 1.3 文档(中文版):https://oner-wv.gitbooks.io/scrapy_zh/content/基本概念/爬虫.html

 

 

 

爬虫(Spiders)

 

Spider 类定义了如何爬取某个(或某些)网站。包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。 换句话说,Spider就是您定义爬取的动作及分析某个网页(或者是有些网页)的地方。

对spider来说,爬取的循环类似下文:

  1. 以初始的URL初始化Request,并设置回调函数。 当该request下载完毕并返回时,将生成response,并作为参数传给该回调函数。

    spider 中初始的 request 是通过调用 start_requests() 来获取的。 start_requests() 读取 start_urls 中的URL, 并以 parse 为回调函数生成 Request 。

  2. 在回调函数内分析返回的(网页)内容,返回 Item 对象或者 Request 或者一个包括二者的可迭代容器。 返回的Request对象之后会经过Scrapy处理,下载相应的内容,并调用设置的callback函数(函数可相同)。

  3. 在回调函数内,您可以使用 选择器(Selectors) (您也可以使用BeautifulSoup, lxml 或者您想用的任何解析器) 来分析网页内容,并根据分析的数据生成item。

  4. 最后,由spider返回的item将被存到数据库(由某些 Item Pipeline 处理)或使用 Feed exports 存入到文件中。

虽然该循环对任何类型的spider都(多少)适用,但Scrapy仍然为了不同的需求提供了多种默认spider。 之后将讨论这些spider。

 

 

scrapy.Spider

 

class scrapy.spiders.Spider

这是最简单的爬虫,每个其他爬虫必须继承该类(包括 Scrapy 自带的一些爬虫,以及你自己写的爬虫)。它不提供任何特殊功能。它只是提供了一个默认的 start_requests() 实现,它读取并请求爬虫的 start_urls 属性,并为每个结果响应调用爬虫的 parse 方法。

  • name:定义此爬虫名称的字符串。爬虫名称是爬虫如何由 Scrapy 定位(和实例化),因此它必须是唯一的。但是,您可以生成多个相同的爬虫实例(instance),这没有任何限制。 name是spider最重要的属性,而且是必须的。如果蜘蛛抓取单个网站(single domain),一个常见的做法是以该网站(domain)(加或不加 后缀 )来命名spider。 例如,如果爬取 mywebsite.com ,该爬虫通常会被命名为 mywebsite 。
  • allowed_domains:可选。包含了此爬虫允许抓取的域的列表。 Requests for URLs not belonging to the domain names specified in this list won’t be followed if OffsiteMiddleware is enabled.
  • start_urls:URL列表。当没有指定特定 URL 时,爬虫将从从该列表中开始抓取。因此,爬取的第一个页面将是这里列出的某个 URL。后续的 URL 将根据包含在起始 URL 中的数据连续生成。
  • custom_settings:该设置是一个dict。运行此爬虫时改设置会覆盖项目级的设置。因为设置在实例化(instantiation)之前更新,所以它必须定义为类属性。有关可用内置设置的列表,请参阅:[ 内置设置参考 ]。

crawler:此属性由初始化类后的类方法 from_crawler() 设置,并链接到此爬虫实例绑定到的 Crawler 对象。Crawlers在项目中封装了很多组件,作为单一入口访问(例如扩展,中间件,信号管理器等)。有关详情,请参阅 Crawler API。

settings:运行此爬虫的配置。这是一个 Settings 实例,请参 设置 来了解详细介绍 。

logger:Python Logger 使用 Spider 的 name 创建。您可以使用它通过它发送日志消息,如从记录日志记录。

from_crawler:这是 Scrapy 用来创建 spider 的类方法。您可能不需要直接复写它,因为默认实现充当 __init __() 方法的代理,使用给定的参数 args 和命名参数 kwargs 调用它。

尽管如此,此方法会在新实例中设置 crawler 和 settings 属性,以便稍后在爬虫代码中访问它们。

参数:

  • crawler(Crawler 实例) -spider将绑定到的crawler
  • args(list) - 传递给 __init __() 方法的参数
  • kwargs(dict) - 传递给 __init __() 方法的关键字参数

start_requests:此方法必须返回一个可迭代对象(iterable),该对象包含了 spider 用于爬取的第一个Request。当 spider 启动时且未指定特定的 URL 时,Scrapy 会调用该方法。如果指定了特定的 URL,则使用 make_requests_from_url() 来创建 Request 对象。此方法仅被调用一次,因此将其作为生成器实现是安全的。该方法的默认实现是使用 start_urls 的 url 生成 Request。如果您想要修改最初爬取某个网站的Request对象,您可以重写(override)该方法。例如,如果您需要在启动时通过使用POST请求登录,您可以:

class MySpider(scrapy.Spider):name = 'myspider'def start_requests(self):return [scrapy.FormRequest("http://www.example.com/login",formdata={'user': 'john', 'pass': 'secret'},callback=self.logged_in)]def logged_in(self, response):# here you would extract links to follow and return Requests for# each of them, with another callbackpass

make_requests_from_url(url):该方法接受一个URL并返回用于爬取的 Request 对象。 该方法在初始化request时被 start_requests() 调用,也被用于转化url为request。默认未被复写(overridden)的情况下,该方法返回的Request对象中, parse() 作为回调函数,dont_filter参数也被设置为开启。 (详情参见 Request)。

parse(response):当response没有指定回调函数时,这是Scrapy用来处理下载的response的默认方法。parse 方法负责处理response并返回所抓取的数据以及(/或)跟进的URL。Spider 对其他的Request的回调函数也有相同的要求。此方法以及任何其他Requestd的回调函数必须返回一个可迭代的 Request 或 dict 或 [Item] 对象。参数:response(Response) - 用于分析的response

log(message[, level, component]):通过 Spider 的 logger 发送日志消息,保留向后兼容性。有关详细信息,请参阅 Logging from Spiders

closed(reason):当spider关闭时,该函数被调用。 该方法提供了一个替代调用signals.connect()来监听 [spider_closed] 信号的快捷方式。

 

让我们看一个例子:

import scrapyclass MySpider(scrapy.Spider):name = 'example.com'allowed_domains = ['example.com']start_urls = ['http://www.example.com/1.html','http://www.example.com/2.html','http://www.example.com/3.html',]def parse(self, response):self.logger.info('A response from %s just arrived!', response.url)

在单个回调函数中返回多个 Request 以及 Item 的例子:

import scrapyclass MySpider(scrapy.Spider):name = 'example.com'allowed_domains = ['example.com']start_urls = ['http://www.example.com/1.html','http://www.example.com/2.html','http://www.example.com/3.html',]def parse(self, response):for h3 in response.xpath('//h3').extract():yield {"title": h3}for url in response.xpath('//a/@href').extract():yield scrapy.Request(url, callback=self.parse)

除了 start_urls ,你也可以直接使用 start_requests() ; 您也可以使用 Items 来给予数据更多的结构性(give data more structure):

import scrapy
from myproject.items import MyItemclass MySpider(scrapy.Spider):name = 'example.com'allowed_domains = ['example.com']def start_requests(self):yield scrapy.Request('http://www.example.com/1.html', self.parse)yield scrapy.Request('http://www.example.com/2.html', self.parse)yield scrapy.Request('http://www.example.com/3.html', self.parse)def parse(self, response):for h3 in response.xpath('//h3').extract():yield MyItem(title=h3)for url in response.xpath('//a/@href').extract():yield scrapy.Request(url, callback=self.parse)

 

 

Spider 参数

 

Spider 可以通过接受参数来修改其功能。 spider参数一般用来定义初始URL或者指定限制爬取网站的部分。 您也可以使用其来配置spider的任何功能。

在运行 crawl 时添加 -a 可以传递Spider参数: scrapy crawl myspider -a category=electronics

Spider 在构造器(constructor)中获取参数:

import scrapyclass MySpider(scrapy.Spider):name = 'myspider'def __init__(self, category=None, *args, **kwargs):super(MySpider, self).__init__(*args, **kwargs)self.start_urls = ['http://www.example.com/categories/%s' % category]# ...

默认的 init 方法将获取任何 spider 参数,并将它们作为 spider 的属性。上面的例子也可以写成如下:

import scrapyclass MySpider(scrapy.Spider):name = 'myspider'def start_requests(self):yield scrapy.Request('http://www.example.com/categories/%s' % self.category)

请记住,蜘蛛参数只能是字符串。蜘蛛自己不会做任何解析。如果要从命令行设置 start_urls 属性,则必须使用 ast.literal_eval 或 json.loads 之类将它解析为列表,并将它设置为属性,然后将其设置为属性。否则,你会导致迭代一个 start_urls 字符串(一个非常常见的python陷阱),导致每个字符被看作一个单独的url。

有效的用例是通过 HttpAuthMiddleware 设置 http auth 证书或 通过 UserAgentMiddleware 设置 user agent:

scrapy crawl myspider -a http_user=myuser -a http_pass=mypassword -a user_agent=mybot

Spider参数也可以通过Scrapyd的 schedule.json API来传递。 参见 Scrapyd documentation.

 

 

Generic Spiders(生成 Spider)

 

Scrapy 自带一些有用的通用爬虫,你可以将自己的爬虫作为它们的子类。他们的目的是为一些常见的抓取案例提供方便的功能,例如根据某些规则跟踪网站上的所有链接,从 Sitemaps 抓取或解析XML / CSV Feed。

对于在下面的爬虫中使用的示例,我们假设你有一个项目,在 myproject.items 模块中声明一个 TestItem

import scrapyclass TestItem(scrapy.Item):id = scrapy.Field()name = scrapy.Field()description = scrapy.Field()

 

CrawlSpider

class scrapy.spiders.CrawlSpider

Scrapy基础——CrawlSpider详解:https://www.jianshu.com/p/0f64297fc912

这是最常用的爬取常规网站的spider,因为它通过定义一组规则为跟进链接提供了一个方便的机制。它可能不是完全适合您的特定网站或项目,但它有足够多的几种通用情况,因此您可以以此为起点,根据需要覆盖更多的自定义功能,当然也可以实现自己的spider。

除了从 Spider 继承的属性(您必须指定),这个类支持一个新的属性:

rules

它是一个(或多个)Rule 对象的列表。每个 Rule 定义用于爬取网址的特定行为。Rule 对象如下所述。如果多个规则匹配相同的链接,则将根据它们在此属性中定义的顺序使用第一个。

该spider也提供了一个可复写(overrideable)的方法:

parse_start_url(response)

对于 start_urls 中url所对应的 response 调用此方法。它允许解析初始响应,并且必须返回 Item 对象,Request 对象或包含其中任何对象的iterable。

 

爬取规则(Crawling rules)

class scrapy.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None)

link_extractor 是一个 链接提取器(Link Extractor)对象,它定义如何从要爬取的页面提取链接。

callback 是一个 callable 或 string(在这种情况下,该spider中同名的函数将会被调用),使用 link_extractor 从 Response 对象中提取的每个链接将会调用该函数。该回调接函数收一个 response 作为它的第一个参数,并且必须返回一个包含 Item 及(或)[Request] 对象(或它们的任何子类)的列表。

警告!

当编写爬虫规则时,避免使用 parse 作为回调,因为 CrawlSpider 使用parse方法本身来实现其逻辑。因此,如果您覆盖 parse 方法,crawl spider 将会运行失败。

[cb_kwargs] 是一个包含要传递给回调函数(keyword argument)的关键字参数的dict。

[follow] 是一个布尔值,指定了根据该规则从response提取的链接是否需要跟进。如果 [callable] 为 None,则默认为 True,否则默认为 False。

[process_links] 是一个 callable 或 string(在这种情况下,该spider中同名的函数将会被调用),使用 link_extractor 从 Response 对象中提取的每个链接列表调用它。这主要用于过滤目的。

[process_request] 是一个 callable 或 string(在这种情况下,该spider中同名的函数将会被调用),它将被此规则提取的每个 request 调用,并且必须返回一个 request 或None(过滤出 request)。

 

CrawlSpider示例

现在让我们来看看一个带有 rule 的 CrawlSpider 示例:

import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractorclass MySpider(CrawlSpider):name = 'example.com'allowed_domains = ['example.com']start_urls = ['http://www.example.com']rules = (# Extract links matching 'category.php' (but not matching 'subsection.php')# and follow links from them (since no callback means follow=True by default).Rule(LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))),# Extract links matching 'item.php' and parse them with the spider's method parse_itemRule(LinkExtractor(allow=('item\.php', )), callback='parse_item'),)def parse_item(self, response):self.logger.info('Hi, this is an item page! %s', response.url)item = scrapy.Item()item['id'] = response.xpath('//td[@id="item_id"]/text()').re(r'ID: (\d+)')item['name'] = response.xpath('//td[@id="item_name"]/text()').extract()item['description'] = response.xpath('//td[@id="item_description"]/text()').extract()return item

该spider将从example.com的首页开始爬取,获取category以及item的链接并对后者使用 parse_item 方法。 当item获得返回(response)时,将使用XPath处理HTML并生成一些数据填入 Item 中。

 

 

 

 

XMLFeedSpider

class scrapy.contrib.spiders.XMLFeedSpider

XMLFeedSpider 被设计用于通过迭代各个节点来分析XML源(XML feed)。 迭代器可以从 iternodes , xml , html 选择。 鉴于 xml 以及 html 迭代器需要先读取所有DOM再分析而引起的性能问题, 一般还是推荐使用 iternodes 。 不过使用 html 作为迭代器能有效应对错误的XML。

您必须定义下列类属性来设置迭代器以及标签名(tag name):

iterator

用于确定使用哪个迭代器的string。可选项有:

  • 'iternodes' - 一个高性能的基于正则表达式的迭代器
  • 'html' - 使用 Selector 的迭代器。 需要注意的是该迭代器使用DOM进行分析,其需要将所有的DOM载入内存, 当数据量大的时候会产生问题。
  • 'xml' - 使用 Selector 的迭代器。 需要注意的是该迭代器使用DOM进行分析,其需要将所有的DOM载入内存, 当数据量大的时候会产生问题。

默认值为 iternodes 。

itertag:一个包含开始迭代的节点名的string。例如:itertag = 'product'

namespaces:一个由 (prefix, url) 元组(tuple)所组成的list。 其定义了在该文档中会被spider处理的可用的namespace。 prefix 及 uri 会被自动调用 register_namespace() 生成namespace。您可以通过在 itertag 属性中制定节点的namespace。例如:

class YourSpider(XMLFeedSpider):namespaces = [('n', 'http://www.sitemaps.org/schemas/sitemap/0.9')]itertag = 'n:url'# ...

除了这些新的属性之外,该spider也有以下可以覆盖(overrideable)的方法:

adapt_response(response):该方法在spider分析response前被调用。您可以在response被分析之前使用该函数来修改内容(body)。 该方法接受一个response并返回一个response(可以相同也可以不同)。

parse_node(responseselector):当节点符合提供的标签名时(itertag)该方法被调用。 接收到的response以及相应的 Selector 作为参数传递给该方法。 该方法返回一个 Item 对象或者 Request 对象 或者一个包含二者的可迭代对象(iterable)。

process_results(responseresults):当spider返回结果(item或request)时该方法被调用。 设定该方法的目的是在结果返回给框架核心(framework core)之前做最后的处理, 例如设定item的ID。其接受一个结果的列表(list of results)及对应的response。 其结果必须返回一个结果的列表(list of results)(包含Item或者Request对象)。

 

XMLFeedSpider例子

该spider十分易用。下边是其中一个例子:

from scrapy.spiders import XMLFeedSpider
from myproject.items import TestItemclass MySpider(XMLFeedSpider):name = 'example.com'allowed_domains = ['example.com']start_urls = ['http://www.example.com/feed.xml']iterator = 'iternodes'  # This is actually unnecessary, since it's the default valueitertag = 'item'def parse_node(self, response, node):self.logger.info('Hi, this is a <%s> node!: %s', self.itertag, ''.join(node.getall()))item = TestItem()item['id'] = node.xpath('@id').get()item['name'] = node.xpath('name').get()item['description'] = node.xpath('description').get()return item

简单来说,我们在这里创建了一个spider,从给定的 start_urls 中下载feed, 并迭代feed中每个 item 标签,输出,并在 Item 中存储有些随机数据。

 

 

CSVFeedSpider

class scrapy.contrib.spiders.CSVFeedSpider

该spider除了其按行遍历而不是节点之外其他和XMLFeedSpider十分类似。 而其在每次迭代时调用的是 parse_row() 。

delimiter:在CSV文件中用于区分字段的分隔符。类型为string。 默认为 ',' (逗号)。

quotechar:A string with the enclosure character for each field in the CSV file Defaults to '"'(quotation mark).

headers:在CSV文件中包含的用来提取字段的行的列表。参考下边的例子。

parse_row(responserow):该方法接收一个response对象及一个以提供或检测出来的header为键的字典(代表每行)。 该spider中,您也可以覆盖 adapt_response 及 process_results 方法来进行预处理(pre-processing)及后(post-processing)处理。

 

CSVFeedSpider例子

下面的例子和之前的例子很像,但使用了 CSVFeedSpider:

from scrapy.spiders import CSVFeedSpider
from myproject.items import TestItemclass MySpider(CSVFeedSpider):name = 'example.com'allowed_domains = ['example.com']start_urls = ['http://www.example.com/feed.csv']delimiter = ';'quotechar = "'"headers = ['id', 'name', 'description']def parse_row(self, response, row):self.logger.info('Hi, this is a row!: %r', row)item = TestItem()item['id'] = row['id']item['name'] = row['name']item['description'] = row['description']return item

 

 

SitemapSpider

class scrapy.contrib.spiders.SitemapSpider

SitemapSpider 使您爬取网站时可以通过 Sitemaps 来发现爬取的URL。

其支持嵌套的 sitemap,并能从 robots.txt 中获取sitemap的url。

sitemap_urls:包含您要爬取的url的sitemap的url列表(list)。 您也可以指定为一个 robots.txt ,spider会从中分析并提取url。

sitemap_rules:一个包含 (regex, callback) 元组的列表(list):

  • regex 是一个用于匹配从sitemap提供的url的正则表达式。 regex 可以是一个字符串或者编译的正则对象(compiled regex object)。
  • callback指定了匹配正则表达式的url的处理函数。 callback 可以是一个字符串(spider中方法的名字)或者是callable。

例如:sitemap_rules = [('/product/', 'parse_product')] 。规则按顺序进行匹配,之后第一个匹配才会被应用。如果您忽略该属性,sitemap中发现的所有url将会被 parse 函数处理。

sitemap_follow:一个用于匹配要跟进的sitemap的正则表达式的列表(list)。其仅仅被应用在 使用 Sitemap index files 来指向其他sitemap文件的站点。默认情况下所有的sitemap都会被跟进。

sitemap_alternate_links:指定当一个 url 有可选的链接时,是否跟进。 有些非英文网站会在一个 url 块内提供其他语言的网站链接。

例如:

<url><loc>http://example.com/</loc><xhtml:link rel="alternate" hreflang="de" href="http://example.com/de"/>
</url>

当 sitemap_alternate_links 设置时,两个URL都会被获取。 当 sitemap_alternate_links 关闭时,有 http://example.com/ 会被获取。默认 sitemap_alternate_links 关闭。

 

sitemap_filter(entries):This is a filter funtion that could be overridden to select sitemap entries based on their attributes.

例如:

<url><loc>http://example.com/</loc><lastmod>2005-01-01</lastmod>
</url>

We can define a sitemap_filter function to filter entries by date:

from datetime import datetime
from scrapy.spiders import SitemapSpiderclass FilteredSitemapSpider(SitemapSpider):name = 'filtered_sitemap_spider'allowed_domains = ['example.com']sitemap_urls = ['http://example.com/sitemap.xml']def sitemap_filter(self, entries):for entry in entries:date_time = datetime.strptime(entry['lastmod'], '%Y-%m-%d')if date_time.year >= 2005:yield entry

This would retrieve only entries modified on 2005 and the following years.

Entries are dict objects extracted from the sitemap document. Usually, the key is the tag name and the value is the text inside it.

It’s important to notice that:

  • as the loc attribute is required, entries without this tag are discarded
  • alternate links are stored in a list with the key alternate (see sitemap_alternate_links)
  • namespaces are removed, so lxml tags named as {namespace}tagname become only tagname

If you omit this method, all entries found in sitemaps will be processed, observing other attributes and their settings.

 

SitemapSpider 样例

简单的例子: 使用 parse 处理通过sitemap发现的所有url:

from scrapy.spiders import SitemapSpiderclass MySpider(SitemapSpider):sitemap_urls = ['http://www.example.com/sitemap.xml']def parse(self, response):pass # ... scrape item here ...

用特定的函数处理某些url,其他的使用另外的callback:

from scrapy.spiders import SitemapSpiderclass MySpider(SitemapSpider):sitemap_urls = ['http://www.example.com/sitemap.xml']sitemap_rules = [('/product/', 'parse_product'),('/category/', 'parse_category'),]def parse_product(self, response):pass # ... scrape product ...def parse_category(self, response):pass # ... scrape category ...

跟进 robots.txt 文件定义的sitemap并只跟进包含有 ..sitemap_shop 的url:

from scrapy.spiders import SitemapSpiderclass MySpider(SitemapSpider):sitemap_urls = ['http://www.example.com/robots.txt']sitemap_rules = [('/shop/', 'parse_shop'),]sitemap_follow = ['/sitemap_shops']def parse_shop(self, response):pass # ... scrape shop here ...

在 SitemapSpider 中使用其他 url:

from scrapy.spiders import SitemapSpiderclass MySpider(SitemapSpider):sitemap_urls = ['http://www.example.com/robots.txt']sitemap_rules = [('/shop/', 'parse_shop'),]other_urls = ['http://www.example.com/about']def start_requests(self):requests = list(super(MySpider, self).start_requests())requests += [scrapy.Request(x, self.parse_other) for x in self.other_urls]return requestsdef parse_shop(self, response):pass # ... scrape shop here ...def parse_other(self, response):pass # ... scrape other here ...

 

 

 

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

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

相关文章

Java8 Stream详解~聚合(max/min/count)

max、min、count这些字眼你一定不陌生&#xff0c;没错&#xff0c;在mysql中我们常用它们进行数据统计。Java stream中也引入了这些概念和用法&#xff0c;极大地方便了我们对集合、数组的数据统计工作。 「案例一&#xff1a;获取String集合中最长的元素。」 public class S…

为何学习新知识这么难?因为大脑可能比你想象中更死板

来源&#xff1a;科研圈撰文 John Rennie 翻译 齐睿娟 审校 魏潇某些情况下&#xff0c;大脑的适应能力似乎是用之不竭的。但通过观察学习状态下的大脑活动&#xff0c;科学家们发现&#xff0c;这一过程中大脑的神经元网络功能出乎意料地死板和低效。学习能力是人类智力的…

vs2010 学习Silverlight学习笔记(8):使用用户控件

概要&#xff1a; 这个类似于封装控件样式。不过封装的是整个或是多个控件罢了&#xff0c;然后用的时候就可以直接引用过来了。 创建用户控&#xff1a; 这个也很简单&#xff0c;不过有几个地方需要注意下。这个就不照抄了&#xff0c;咱们也自己写一个。  步骤&#xff1a…

群雄逐鹿,谁将赢得5G时代的物联网战争?

来源&#xff1a;IT港摘要&#xff1a;5G时代的物联网机遇&#xff0c;是一次重大产业变革机会&#xff0c;谁都不想错过&#xff0c;但谁能享受到这波红利&#xff0c;我们还需拭目以待。日本首富&#xff0c;软银集团创始人孙正义是全球科技界的传奇&#xff0c;他曾投资了两…

Java8 Stream详解~映射(map/flatMap)

映射&#xff0c;可以将一个流的元素按照一定的映射规则映射到另一个流中。分为map和flatMap&#xff1a; map&#xff1a;接收一个函数作为参数&#xff0c;该函数会被应用到每个元素上&#xff0c;并将其映射成一个新的元素。 flatMap&#xff1a;接收一个函数作为参数&…

Scrapy-redis 源码分析 及 框架使用

From&#xff1a;https://blog.csdn.net/weixin_37947156/article/details/75044971 From&#xff1a;https://cuiqingcai.com/6058.html Scrapy-redis github&#xff1a;https://github.com/rmax/scrapy-redis scrapy-redis分布式爬虫框架详解&#xff1a;https://segmentfa…

收集一些.NET开发资源站点和部分优秀.NET开源项目 (转)

收集一些.NET开发资源站点和部分优 秀.NET开源项目 微软.Net中文主页 .NET Framework开发中心 微软.Net Framework中文产品支持中心 微软.Net Framework中文新闻组(Web) 微软VB.Net中文新闻组(Web) 博客园 .NET 2.0 专题 孟宪会之精彩世界 微软.NET俱乐部 MSDN中文网络广播 As…

Java8 Stream详解~归约(reduce)

归约&#xff0c;也称缩减&#xff0c;顾名思义&#xff0c;是把一个流缩减成一个值&#xff0c;能实现对集合求和、求乘积和求最值操作。 「案例一&#xff1a;求Integer集合的元素之和、乘积和最大值。」 public class StreamTest {public static void main(String[] args) …

人工智能除了创造新材料还能预测化学反应性能

来源&#xff1a; 材料牛摘要&#xff1a; 在材料化学领域人工智能也在发挥着越来越重要的作用&#xff0c;往往研究人员想尽脑汁做不出来的东西它可以经过成千上万次的计算给出最优答案。【引言】机器学习方法正在成为众多学科科学探究的一部分。 机器学习&#xff08;ML&…

scrapy-redis 配置 settings

From&#xff1a;https://blog.csdn.net/weixin_37947156/article/details/75082061 小白进阶之Scrapy第三篇&#xff08;基于Scrapy-Redis的分布式以及cookies池&#xff09;&#xff1a;https://cuiqingcai.com/4048.html 开始之前我们得知道scrapy-redis的一些配置&#xf…

叶问2

编剧都死绝了&#xff1f;这么弱智的剧情&#xff01;还不如直接请甄子丹拍武打教学片&#xff01;还有那个狗屁《十月围城》居然是金像奖的大赢家&#xff0c;真他妈的活见鬼&#xff01;转载于:https://www.cnblogs.com/uwenida/archive/2010/05/11/1732983.html

推荐|深度学习领域引用量最多的前20篇论文简介

来源&#xff1a;全球人工智能作者&#xff1a;Pedro Lopez&#xff0c;数据科学家&#xff0c;从事金融与商业智能。译者&#xff1a;海棠&#xff0c;审阅&#xff1a;袁虎。深度学习是机器学习和统计学交叉领域的一个子集&#xff0c;在过去的几年里得到快速的发展。强大的开…

Java8 Stream详解~收集(collect)

collect&#xff0c;收集&#xff0c;可以说是内容最繁多、功能最丰富的部分了。从字面上去理解&#xff0c;就是把一个流收集起来&#xff0c;最终可以是收集成一个值也可以收集成一个新的集合。 1 归集(toList/toSet/toMap) 因为流不存储数据&#xff0c;那么在流中的数据完…

CrawlSpider 详解

From&#xff1a;https://blog.csdn.net/weixin_37947156/article/details/75604163 CrawlSpider是爬取那些具有一定规则网站的常用的爬虫&#xff0c;它基于Spider并有一些独特属性 rules: 是Rule对象的集合&#xff0c;用于匹配目标网站并排除干扰parse_start_url: 用于爬取…

MFC中实现的画箭头算法 (Arrow in MFC)

在codeproject中寻找到一个这样的算法,在这里介绍一下 可以改变三角形大小,顶点角度,是否填充和填充颜色等 但是画出的箭头还是不够美观....呵呵,还好吧 其中填充是代表箭头内是否填充颜色 先来看声明和实现 //使用一个结构体来存储相关的信息//Defines the attributes of…

Java8 Stream详解~排序:sorted

sorted&#xff0c;中间操作。有两种排序&#xff1a; sorted()&#xff1a;自然排序&#xff0c;流中元素需实现Comparable接口 sorted(Comparator com)&#xff1a;Comparator排序器自定义排序 「案例&#xff1a;将员工按工资由高到低&#xff08;工资一样则按年龄由大到小…

英国上议院AI报告:没中美有钱,但我可以主导道德游戏规则设定

来源&#xff1a;网络大数据随着全球各国政府纷纷计划推出 AI 驱动下的未来&#xff0c;英国正准备承担一些学术和道德上的责任。最近&#xff0c;英国上议院 (House of Lords) 发布了一份183页的 报告《AI in the UK: ready, willing and able?》(《人工智能在英国&#xff1…

Java8 Stream详解~ 提取/组合

流也可以进行合并、去重、限制、跳过等操作。 public class StreamTest {public static void main(String[] args) {String[] arr1 { "a", "b", "c", "d" };String[] arr2 { "d", "e", "f", "g&…

Scrapy 下载器 中间件(Downloader Middleware)

Scrapy 下载器中间件官方文档&#xff1a;https://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/downloader-middleware.html 官方 英文 文档&#xff1a;http://doc.scrapy.org/en/latest/topics/downloader-middleware.html#topics-downloader-middleware Scrapy 扩展中间件…

15 个 JavaScript Web UI 库

转载http://news.csdn.net/a/20100519/218442.html 几乎所有的富 Web 应用都基于一个或多个 Web UI 库或框架&#xff0c;这些 UI 库与框架极大地简化了开发进程&#xff0c;并带来一致&#xff0c;可靠&#xff0c;以及高度交互性的用户界面。本文介绍了 15 个非常强大的 Java…