python爬虫框架scrapyscrapy建立索引是在什么时候

python爬虫系统学习十三:Scrapy使用
python爬虫系统学习十三:Scrapy使用
技术的反应器
Scrapy使用Scrapy是基于Python的分布式爬虫框架,使用它可以非常方便地实现分布式爬虫。Scrapy高度灵活可定制,让你的写出的爬虫可以应对各种网站情况。同时Scrapy封装了很多爬虫的实现细节,所以可以把更多的精力放在数据的提取上。这一章,将会在Python 2 环境下安装和使用Scrapy,有人推举直接安装Anaconda他包含了所有的scrapy组件,但他也包含了我们用不到的组件所以还是直接安装scrapy!在安装scrapy之前 先要安装一个VC++8.0 应为后面安装scrapy的其中一个依赖库必须要使用它来编译,直接在微软官网上下载安装就ok/en-us/download/details.aspx?id=44266安装pywin32,在下面的连接中下载最新版的pywin32http://sourceforge.net/projects/pywin32/files/pywin32/接着安装lxml,直接使用命令pip install lxml来安装然后就可以运行命令:pip install scrapy来安装scrapy了,pip会自动安装Scrapy所需要的其他第三方库。Scrapy所需要依赖的第三方库非常多,所以会花比较长的时间才能安装完成。如图所示为安装Scrapy的时候,自动安装的依赖(部分):创建项目然后再cmd命令行进到你源代码存放的目录运行scrapy startproject tutorial 来创建scrapy项目上面的“tutorial”为工程名,可以使用大部分的英文单词或者词组或者字母加数字。但是工程名绝对不能为&scrapy&或者Python的第三方库的名字。否则会导致Python的包导入问题。打开刚刚创建好的工程,可以看到如下图所示的目录结构:然后就可以在spiders目录下创建我们的爬虫文件了在图中也可以看到我之前创建的example.py文件的内容。请注意第6行:这就是告诉Scrapy, 这个爬虫的名字叫做&example&。现在,只修改一行内容,看看是什么效果。将第13行的pass修改为下面的代码:爬虫的运行然后运行一下Scrapy的爬虫。需要注意的是,Scrapy的爬虫不能直接运行example.py这个文件,需要在CMD里面进入工程的根目录运行以下命令:终端窗口中滚过很多的字符,但是似乎没有看到百度首页的源代码被打印出来。如果仔细看终端中的内容,将会发现下图中被圈出来的两条信息:不过没关系,请打开工程中的settings.py文件,将会在里面看到:再次运行,就可以看到百度的源代码被打印了出来:由于Scrapy爬虫的运行方式和我们以前的爬虫不同,不能直接运行爬虫代码所在的.py文件。那如何使用Pycharm运行爬虫呢?在工程的根目录下面创建一个main.py文件,内容如下:然后使用Python来运行这个main.py文件即可。如下图所示:还可以试一试在example.py文件中下一个断点并启动调试功能,会发现调试功能也可以正常运行。既然网页的源代码已经被拿下来了,那接下来的工作就是提取信息。如果前面XPath学得不错的话,可以在5分钟之内掌握使用Scrapy提取信息的办法。请看下图第13和14行代码:Scrapy与lxml在使用XPath的唯一不同之处在于,当要把获取到的字符串内容提取出来的时候,Scrapy的语句需要用.extract()这个方法。如果暂时不需要把内容提取出来,那么可以先不需要使用.extract()方法,比如在先抓大再抓小这个技巧中,我们有两个XPath:需要把每一对的链接和name文字对应起来。但是由于有时候,有一些name标签缺失,如果把它们分开获取就没有办法做到一一对应。所以可以这样写:使用这种方式,就把链接和文字一一对应起来了。如果本身没有文字,就使用N/A代替。更多练习,可以访问/overall 。最后来讲讲以前遗留的问题mongodb安装为windows服务之前第一章的时候介绍安装并启动了mongodb数据库,事实上每次通过命令行启动Mongo是痛苦的,因此我们需要建立一个永久性服务,这就需要我们把Mongo加入到Windows本地服务中去先介绍一下目录结构bin目录是mongodb程序目录 ,data\db\是数据存放目录 log是日志目录在F:\mongodb\data下新建文件夹log(存放日志文件)并且新建文件mongodb.log在F:\mongodb新建文件mongo.config用记事本打开mongo.config输入:dbpath=D:\mongodb\data\dblogpath=D:\mongodb\data\log\mongo.log然后再bin目录下打开命令行输入如下命令mongod --dbpath &F:\mongodb\data\db& --logpath &F:\mongodb\data\log\mongodb.log& --install --serviceName &MongoDB&显示为如下图所示说明服务已经安装成功了mongodb相比mysql速度快了但就是安装起来就很不友好了!本次安环境为windows10 64专业版其亲测可以使用!
本文仅代表作者观点,不代表百度立场。系作者授权百家号发表,未经许可不得转载。
技术的反应器
百家号 最近更新:
简介: 聚焦机器人领域和智能家居,泛科技类来自媒体
作者最新文章Scrapy爬虫入门教程四 Spider(爬虫) - 简书
Scrapy爬虫入门教程四 Spider(爬虫)
开发环境:Python 3.6.0 版本 (当前最新)Scrapy 1.3.2 版本 (当前最新)
爬虫是定义如何抓取某个网站(或一组网站)的类,包括如何执行抓取(即关注链接)以及如何从其网页中提取结构化数据(即抓取项目)。换句话说,Spider是您定义用于为特定网站(或在某些情况下,一组网站)抓取和解析网页的自定义行为的位置。
对于爬虫,循环经历这样的事情:
您首先生成用于抓取第一个URL的初始请求,然后指定要使用从这些请求下载的响应调用的回调函数。
第一个执行的请求通过调用 start_requests()(默认情况下)Request为在start_urls和中指定的URL生成的parse方法获取, 并且该方法作为请求的回调函数。
在回调函数中,您将解析响应(网页),并返回带有提取的数据,Item对象, Request对象或这些对象的可迭代的对象。这些请求还将包含回调(可能是相同的),然后由Scrapy下载,然后由指定的回调处理它们的响应。
在回调函数中,您通常使用选择器来解析页面内容 (但您也可以使用BeautifulSoup,lxml或您喜欢的任何机制),并使用解析的数据生成项目。
最后,从爬虫返回的项目通常将持久存储到数据库(在某些项目管道中)或使用Feed导出写入文件。
即使这个循环(或多或少)适用于任何种类的爬虫,有不同种类的默认爬虫捆绑到Scrapy中用于不同的目的。我们将在这里谈论这些类型。
class scrapy.spiders.Spider
这是最简单的爬虫,每个其他爬虫必须继承的爬虫(包括与Scrapy捆绑在一起的爬虫,以及你自己写的爬虫)。它不提供任何特殊功能。它只是提供了一个默认start_requests()实现,它从start_urlsspider属性发送请求,并parse 为每个结果响应调用spider的方法。
name定义此爬虫名称的字符串。爬虫名称是爬虫如何由Scrapy定位(和实例化),因此它必须是唯一的。但是,没有什么能阻止你实例化同一个爬虫的多个实例。这是最重要的爬虫属性,它是必需的。
如果爬虫抓取单个域名,通常的做法是在域后面命名爬虫。因此,例如,抓取的爬虫通常会被调用 mywebsite。
注意在Python 2中,这必须是ASCII。
allowed_domains允许此爬虫抓取的域的字符串的可选列表,指定一个列表可以抓取,其它就不会抓取了。
start_urls当没有指定特定网址时,爬虫将开始抓取的网址列表。
custom_settings运行此爬虫时将从项目宽配置覆盖的设置字典。它必须定义为类属性,因为设置在实例化之前更新。
有关可用内置设置的列表,请参阅: 。
crawler此属性from_crawler()在初始化类后由类方法设置,并链接Crawler到此爬虫实例绑定到的对象。
Crawlers在项目中封装了很多组件,用于单个条目访问(例如扩展,中间件,信号管理器等)。有关详情,。
settings运行此爬虫的配置。这是一个 Settings实例,有关此主题的详细介绍,。
logger用Spider创建的Python记录器name。您可以使用它通过它发送日志消息,如。
from_crawler(crawler, args,* kwargs )是Scrapy用来创建爬虫的类方法。
您可能不需要直接覆盖这一点,因为默认实现充当方法的代理,__init__()使用给定的参数args和命名参数kwargs调用它。
尽管如此,此方法 在新实例中设置crawler和settings属性,以便以后可以在爬虫程序中访问它们。
crawler(Crawlerinstance) - 爬虫将绑定到的爬虫
args(list) - 传递给init()方法的参数
kwargs(dict) - 传递给init()方法的关键字参数
start_requests()此方法必须返回一个可迭代的第一个请求来抓取这个爬虫。
有了start_requests(),就不写了start_urls,写了也没有用。
默认实现是:start_urls,但是可以复写的方法start_requests。例如,如果您需要通过使用POST请求登录来启动,您可以:
class MySpider(scrapy.Spider):
name = 'myspider'
def start_requests(self):
return [scrapy.FormRequest("/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 callback
make_requests_from_url(url)一种接收URL并返回Request 对象(或Request对象列表)进行抓取的方法。此方法用于在方法中构造初始请求 start_requests(),并且通常用于将URL转换为请求。
除非重写,此方法返回具有方法的Requests parse() 作为它们的回调函数,并启用dont_filter参数(Request有关更多信息,请参阅类)。
parse(response)这是Scrapy用于处理下载的响应的默认回调,当它们的请求没有指定回调时。
该parse方法负责处理响应并返回所抓取的数据或更多的URL。其他请求回调具有与Spider类相同的要求。
此方法以及任何其他请求回调必须返回一个可迭代的Request和dicts或Item对象。
response(Response) - 解析的响应
log(message[, level, component])包装器通过爬虫发送日志消息logger,保持向后兼容性。有关详细信息,请参阅 从Spider记录。
closed(reason)当爬虫关闭时召唤。此方法为spider_closed信号的signals.connect()提供了一个快捷方式。
让我们看一个例子:
import scrapy
class MySpider(scrapy.Spider):
allowed_domains = ['']
start_urls = [
'/1.html',
'/2.html',
'/3.html',
def parse(self, response):
('A response from %s just arrived!', response.url)
从单个回调中返回多个请求和项:
import scrapy
class MySpider(scrapy.Spider):
allowed_domains = ['']
start_urls = [
'/1.html',
'/2.html',
'/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_requests(),而不是start_ 项目可以更加方便获取数据:
import scrapy
from myproject.items import MyItem
class MySpider(scrapy.Spider):
allowed_domains = ['']
def start_requests(self):
yield scrapy.Request('/1.html', self.parse)
yield scrapy.Request('/2.html', self.parse)
yield scrapy.Request('/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 arguments
爬虫可以接收修改其行为的参数。爬虫参数的一些常见用法是定义起始URL或将爬网限制到网站的某些部分,但它们可用于配置爬虫的任何功能。
Spider crawl参数使用该-a选项通过命令 传递。例如:
scrapy crawl myspider -a category=electronics
爬虫可以在他们的init方法中访问参数:
import scrapy
class MySpider(scrapy.Spider):
name = 'myspider'
def __init__(self, category=None, *args, **kwargs):
super(MySpider, self).__init__(*args, **kwargs)
self.start_urls = ['/categories/%s' % category]
默认的init方法将获取任何爬虫参数,并将它们作为属性复制到爬虫。上面的例子也可以写成如下:
import scrapy
class MySpider(scrapy.Spider):
name = 'myspider'
def start_requests(self):
yield scrapy.Request('/categories/%s' % self.category)
请记住,spider参数只是字符串。爬虫不会自己做任何解析。如果要从命令行设置start_urls属性,则必须将它自己解析为列表,使用像 ast.literal_eval 或json.loads之类的属性 ,然后将其设置为属性。否则,你会导致迭代一个start_urls字符串(一个非常常见的python陷阱),导致每个字符被看作一个单独的url。
有效的用例是设置使用的http验证凭据HttpAuthMiddleware 或用户代理使用的用户代理UserAgentMiddleware:scrapy crawl myspider -a http_user=myuser -a http_pass=mypassword -a user_agent=mybot
Spider参数也可以通过Scrapyd schedule.jsonAPI 传递。请参阅。
Scrapy附带一些有用的通用爬虫,你可以使用它来子类化你的爬虫。他们的目的是为一些常见的抓取案例提供方便的功能,例如根据某些规则查看网站上的所有链接,从站点或解析XML / CSV Feed。
对于在以下爬虫中使用的示例,我们假设您有一个TestItem在myproject.items模块中声明的项目:
import scrapy
class TestItem(scrapy.Item):
id = scrapy.Field()
name = scrapy.Field()
description = scrapy.Field()
类 scrapy.spiders.CrawlSpider这是最常用的爬行常规网站的爬虫,因为它通过定义一组规则为下列链接提供了一种方便的机制。它可能不是最适合您的特定网站或项目,但它是足够通用的几种情况,所以你可以从它开始,根据需要覆盖更多的自定义功能,或只是实现自己的爬虫。
除了从Spider继承的属性(你必须指定),这个类支持一个新的属性:
rules它是一个(或多个)Rule对象的列表。每个都Rule定义了抓取网站的某种行为。规则对象如下所述。如果多个规则匹配相同的链接,则将根据它们在此属性中定义的顺序使用第一个。
这个爬虫还暴露了可覆盖的方法:
parse_start_url(response)对于start_urls响应调用此方法。它允许解析初始响应,并且必须返回Item对象,Request对象或包含任何对象的迭代器。
class scrapy.spiders.Rule(link_extractor,callback = None,cb_kwargs = None,follow = None,process_links = None,process_request = None )link_extractor是一个链接提取程序对象,它定义如何从每个爬网页面提取链接。
callback是一个可调用的或字符串(在这种情况下,将使用具有该名称的爬虫对象的方法),以便为使用指定的link_extractor提取的每个链接调用。这个回调接收一个响应作为其第一个参数,并且必须返回一个包含Item和 Request对象(或它们的任何子类)的列表。
警告当编写爬网爬虫规则时,避免使用parse作为回调,因为CrawlSpider使用parse方法本身来实现其逻辑。所以如果你重写的parse方法,爬行爬虫将不再工作。
cb_kwargs 是包含要传递给回调函数的关键字参数的dict。
follow是一个布尔值,它指定是否应该从使用此规则提取的每个响应中跟踪链接。如果callback是None follow默认为True,否则默认为False。
process_links是一个可调用的或一个字符串(在这种情况下,将使用具有该名称的爬虫对象的方法),将使用指定从每个响应提取的每个链接列表调用该方法link_extractor。这主要用于过滤目的。
process_request 是一个可调用的或一个字符串(在这种情况下,将使用具有该名称的爬虫对象的方法),它将被此规则提取的每个请求调用,并且必须返回一个请求或无(过滤出请求) 。
抓取爬虫示例
现在让我们来看一个CrawlSpider的例子:
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
class MySpider(CrawlSpider):
allowed_domains = ['']
start_urls = ['']
# 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_item
Rule(LinkExtractor(allow=('item\.php', )), callback='parse_item'),
def parse_item(self, response):
('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
这个爬虫会开始抓取的主页,收集类别链接和项链接,用parse_item方法解析后者。对于每个项目响应,将使用XPath从HTML中提取一些数据,并将Item使用它填充。
XMLFeedSpider
class scrapy.spiders.XMLFeedSpiderXMLFeedSpider设计用于通过以特定节点名称迭代XML订阅源来解析XML订阅源。迭代器可以选自:iternodes,xml和html。iternodes为了性能原因,建议使用迭代器,因为xml和迭代器html一次生成整个DOM为了解析它。但是,html当使用坏标记解析XML时,使用作为迭代器可能很有用。
要设置迭代器和标记名称,必须定义以下类属性:
iterator定义要使用的迭代器的字符串。它可以是:
'iternodes' - 基于正则表达式的快速迭代器
'html'- 使用的迭代器Selector。请记住,这使用DOM解析,并且必须加载所有DOM在内存中,这可能是一个大饲料的问题
'xml'- 使用的迭代器Selector。请记住,这使用DOM解析,并且必须加载所有DOM在内存中,这可能是一个大饲料的问题它默认为:'iternodes'。
itertag一个具有要迭代的节点(或元素)的名称的字符串。示例:itertag = 'product'
namespaces定义该文档中将使用此爬虫处理的命名空间的元组列表。在 与将用于自动注册使用的命名空间 的方法。(prefix, uri)prefixuriregister_namespace()
然后,您可以在属性中指定具有命名空间的itertag 节点。
class YourSpider(XMLFeedSpider):
namespaces = [('n', 'http://www.sitemaps.org/schemas/sitemap/0.9')]
itertag = 'n:url'
除了这些新的属性,这个爬虫也有以下可重写的方法:
adapt_response(response)一种在爬虫开始解析响应之前,在响应从爬虫中间件到达时立即接收的方法。它可以用于在解析之前修改响应主体。此方法接收响应并返回响应(它可以是相同的或另一个)。
parse_node(response, selector)对于与提供的标记名称(itertag)匹配的节点,将调用此方法。接收Selector每个节点的响应和 。覆盖此方法是必需的。否则,你的爬虫将不工作。此方法必须返回一个Item对象,一个 Request对象或包含任何对象的迭代器。
process_results(response, results)对于由爬虫返回的每个结果(Items or Requests),将调用此方法,并且它将在将结果返回到框架核心之前执行所需的任何最后处理,例如设置项目ID。它接收结果列表和产生那些结果的响应。它必须返回结果列表(Items or Requests)。
XMLFeedSpider示例
这些爬虫很容易使用,让我们看一个例子:
from scrapy.spiders import XMLFeedSpider
from myproject.items import TestItem
class MySpider(XMLFeedSpider):
allowed_domains = ['']
start_urls = ['/feed.xml']
iterator = 'iternodes'
# This is actually unnecessary, since it's the default value
itertag = 'item'
def parse_node(self, response, node):
('Hi, this is a &%s& node!: %s', self.itertag, ''.join(node.extract()))
item = TestItem()
item['id'] = node.xpath('@id').extract()
item['name'] = node.xpath('name').extract()
item['description'] = node.xpath('description').extract()
return item
基本上我们做的是创建一个爬虫,从给定的下载一个start_urls,然后遍历每个item标签,打印出来,并存储一些随机数据Item。
CSVFeedSpider
class scrapy.spiders.CSVF这个爬虫非常类似于XMLFeedSpider,除了它迭代行,而不是节点。在每次迭代中调用的方法是parse_row()。
delimiterCSV文件中每个字段的带分隔符的字符串默认为','(逗号)。
quotecharCSV文件中每个字段的包含字符的字符串默认为'"'(引号)。
headers文件CSV Feed中包含的行的列表,用于从中提取字段。
parse_row(response, row)使用CSV文件的每个提供(或检测到)标头的键接收响应和dict(表示每行)。这个爬虫还给予机会重写adapt_response和process_results方法的前和后处理的目的。
CSVFeedSpider示例
让我们看一个类似于前一个例子,但使用 CSVFeedSpider:
from scrapy.spiders import CSVFeedSpider
from myproject.items import TestItem
class MySpider(CSVFeedSpider):
allowed_domains = ['']
start_urls = ['/feed.csv']
delimiter = ';'
quotechar = "'"
headers = ['id', 'name', 'description']
def parse_row(self, response, row):
('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.spiders.SitemapSpiderSitemapSpider允许您通过使用发现网址来抓取。
它支持嵌套Sitemap和从发现Sitemap网址 。
sitemap_urls指向您要抓取的网址的网站的网址列表。
您还可以指向robots.txt,它会解析为从中提取Sitemap网址。
sitemap_rules元组列表其中:(regex, callback)
regex是与从Sitemap中提取的网址相匹配的正则表达式。 regex可以是一个str或一个编译的正则表达式对象。
callback是用于处理与正则表达式匹配的url的回调。callback可以是字符串(指示蜘蛛方法的名称)或可调用的。
例如:sitemap_rules = [('/product/', 'parse_product')]
规则按顺序应用,只有匹配的第一个将被使用。如果省略此属性,则会在parse回调中处理在站点地图中找到的所有网址。
sitemap_follow应遵循的网站地图的正则表达式列表。这只适用于使用指向其他Sitemap文件的的网站。
默认情况下,将跟踪所有网站地图。
sitemap_alternate_links指定是否url应遵循一个备用链接。这些是在同一个url块中传递的另一种语言的同一网站的链接。
&loc&/&/loc&
&xhtml:link rel="alternate" hreflang="de" href="/de"/&
使用sitemap_alternate_linksset,这将检索两个URL。随着 sitemap_alternate_links禁用,只有
默认为sitemap_alternate_links禁用。
SitemapSpider示例
最简单的示例:使用parse回调处理通过站点地图发现的所有网址 :
from scrapy.spiders import SitemapSpider
class MySpider(SitemapSpider):
sitemap_urls = ['/sitemap.xml']
def parse(self, response):
pass # ... scrape item here ...
使用某个回调处理一些网址,并使用不同的回调处理其他网址:
from scrapy.spiders import SitemapSpider
class MySpider(SitemapSpider):
sitemap_urls = ['/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 ...
关注文件中定义的sitemaps,并且只跟踪其网址包含/sitemap_shop以下内容的Sitemap :
from scrapy.spiders import SitemapSpider
class MySpider(SitemapSpider):
sitemap_urls = ['/robots.txt']
sitemap_rules = [
('/shop/', 'parse_shop'),
sitemap_follow = ['/sitemap_shops']
def parse_shop(self, response):
pass # ... scrape shop here ...
将SitemapSpider与其他来源网址结合使用:
from scrapy.spiders import SitemapSpider
class MySpider(SitemapSpider):
sitemap_urls = ['/robots.txt']
sitemap_rules = [
('/shop/', 'parse_shop'),
other_urls = ['/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 requests
def parse_shop(self, response):
pass # ... scrape shop here ...
def parse_other(self, response):
pass # ... scrape other here ...备注:本文来自于复制摘抄。
安装上,windows反而很顺利,在搬瓦工的VPS上安装时需要注意一些问题。首先是升级python到2.7版,这是scrapy需求的,这个问题网上有很多现成的教程,不需要重复了。python升级之后,仍然可能安装失败,需要安装一些python开发库,主要是下面这些:
1yum install python-devel libxml2-devel libxslt-devel
yuminstall
用scrapy建立工程之后,在spiders目录下添加python文件编写爬虫时,最好不要让文件名和工程名一样,否则你从上一级目录导入自定义的item类时会出问题。scrapy shell在cygwin的terminal下运行有问题,改回windows的cmd环境就正常了。爬虫代码中,如果需要调试信息,用logging模块而不是print,print要等到爬虫运行完之后才会打印,而logging是即时的。如果想减少一些爬虫的调试信息,可以在setting.py中巴log_level调高,默认是DEBUG,改成INFO,或者WARNING可以减少很多不必要的信息,但这是在你确保爬虫没问题之后才能做的。自己写的pipeline一定要在setting.py中添加进去,否则是无效的。DropItem是一个异常调用,应该写raise DropItem(‘your info’),而不是把它当一个普通函数来调用,那样是无效的。爬虫要爬哪些URL,这个是不需要担心会重复的,scrapy自己的调度系统里面有基本的duplicate filter,但是获取的item是否有重复,就需要你自己在pipeline里面判断了。因为url不用担心重复,所以你在枚举下一级的链接时,可以放心大胆的yield大量页面链接,我刚开始担心有重复,每次只yield下一页的链接给parser,结果速度非常慢。不要爬墙外的网站,除非你有绝对稳定的翻墙途径,否则在爬了一大半之后看到一堆twisted io error然后爬虫挂掉,真是很痛苦的事情。最好直接把爬虫放在国外服务器上爬被墙的网站,事实证明国外的VPS比国内最快的翻墙路线执行爬虫的速度还要快三倍。Concurrent Connection Per IP/Domain可以调大,16线程是小意思,默认的8线程太慢了。
1from scrapy.exceptions import CloseSpider这个异常可以用来手动关闭爬虫,记住,和DropItem一样,这是个异常,要raise而不是调用。使用selector匹配网页内容时,要多挑写页面测试xpath规则,因为某些元素在第一页存在,在后面的页面中就不一定存在了,这样xpath extract出来的可能是个None,这个时候你还用原有的规则取第一个元素,就可能爆IndexError Exception,直接让程序停掉。任何Exception都可以让爬虫停掉,所以一定要多做抽样测试,免得跑了一半挂掉,再改程序重跑。我建议的检查顺序是,先关闭pipeline,也不做具体内容抽取,只先做链接抽取,这样让爬虫跑一段看看Console的输出信息,先确定自己要抓的各种链接都有被覆盖。然后就是抽一部分页面做具体内容抓取,确保你用的xpath规则能覆盖所有页面而不报错,如果单纯的xpath规则不行,你要考虑xpath+re正则表达式,后者的鲁棒性要好很多。对于ajax内容,要分析网页,找出最终的数据来源。因为ajax的本质就是javascript在你本地的浏览器执行,偷偷的又向服务器查询了一次数据用于填充页面,你只要找出这个偷偷查询的内容,然后用requests之类的模块查询一次就可以了。对于普通的link,scrapy本身会检查并确保页面被成功抓取(在网络没断的前提下),基本不用担心数据完整性。对于ajax内容你用其他方式查询了数据的,需要处理好查询方法的返回值,在没有查询成功的情况下,可以让pipeline有个标志位来判断是否需要重新抓取,还是把这些不完整的数据存到另一个数据库以后再修补。在匹配xpath规则时,如果你在firebug中调试,请一定先用Noscript之类的插件禁用脚本。因为有些网站在启用js和不用js的情况下,很多元素的class名字是不一样的,而爬虫看到的页面永远是没有js脚本执行的,最简单的方法还是先用scrapy shell抓一个页面,测试好xpath规则之后再写代码。对于日文页面,标准的‘GBK’编码可能不足以显示所有字符,可以用str.encode(‘GB18030’)的方式先扩到GB18030编码,这个编码基本是可以覆盖CJK所有字符的。对于matplotlib中,生成图片里中文的乱码,加上下面这样一行,给中文指定个中文字体就好了。
matplotlib.rcParams['font.sans-serif']=
['SimHei']
&当数据量大的时候,保存数据用jsonlines而不是json,这样就算有个别数据因为网络或文件io问题不完整的时候,顶多损失一行数据,而不需要再一个几十万字节长的单行里查找哪里错了。
本文已收录于以下专栏:
相关文章推荐
/blog/scrapy%E4%B8%AD%E6%96%87%E7%BC%96%E7%A0%81%E9%97%AE%E9%A2%98
http://...
用Scrapy框架爬取网页的一系列技术文章,以伯乐在线为例(网址为/tag/machinelearning/)。通过查看网站源码获取每篇文章的链接和标题,...
人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..
http://my.oschina.net/u/1024140/blog/188154
近期找工作略不顺。技术无用。晚上写下了这点东西。
首先说下最近在找工作的x的大概相关技术加点路线。p...
这几天学习了一下scrapy爬虫,总结一下一些经验教训。
安装上,windows反而很顺利,在搬瓦工的VPS上安装时需要注意一些问题。首先是升级python到2.7版,这是scrapy需求的,这...
大家有没有发现之前我们写的爬虫都有一个共性,就是只能爬取单纯的html代码,如果页面是JS渲染的该怎么办呢?如果我们单纯去分析一个个后台的请求,手动去摸索JS渲染的到的一些结果,那简直没天理了...
在上一节我们学习了 PhantomJS 的基本用法,归根结底它是一个没有界面的浏览器,而且运行的是 JavaScript 脚本,然而这就能写爬虫了吗?这又和Python有什么关系?说好的Pyt...
本博客地址【http://blog.csdn.net/xiantian7】
一、Scrapy 概览
Scrapy 是一款抓取网页并从中提取结构化数据的应用程序框架,它具有非常广泛的应用场景,如...
爬虫框架Scrapy的第一个爬虫示例入门教程。
我们使用dmoz.org这个网站来作为小抓抓一展身手的对象。
首先先要回答一个问题。
问:把网站装进爬虫里,总共分几步?
答案很简单,四步:
Scrapy爬虫(六):多个爬虫组合实例Scrapy爬虫六多个爬虫组合实例
本章将实现多个爬虫共同工作的实例。
需求分析我们现在有这么个需求,既要爬取音乐详情又要爬取...
这篇文章中写了常用的下载中间件的用法和例子。
Downloader Middleware处理的过程主要在调度器发送requests请求的时候以及网页将response结果返回给spiders的时候,...
他的最新文章
讲师:汪剑
讲师:陈守元
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 python爬虫框架scrapy 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信