如何用scrapy 递归抓取抓取数据时使用Xpath获得全部文本

前言:前面已经抓取到了一页博文的数据,但是我想把整个博客的标题和链接抓取下来,文章内容暂缓
0x2 yield知识
0x3 整个Spider功能实现;
0x4 运行结果
前言:前面已经抓取到了一页博文的数据,但是我想把整个博客的标题和链接抓取下来,文章内容暂缓0x1 思路0x2 yield知识0x3 整个Spider功能实现;0x4 运行结果
我们只需要在parse 功能函数下做两件事:
1 执行单个页面的数据提取
2 继续Request下页,并使用回调parse处理新页面的Parse
0x2 yield知识;
中文可译为“迭代产生器,”,与直接return不同的是,return只保存1次值,程序就返回了(执行完毕),什么意思,如果我想在某个循环内for i in xx,想保留每次循环的变量i,return 只能保留最开始的一次,然后直接退出程序,而yield刚好弥补了这块空白,可以把每次执行的状态值i保留,这样我就能把每次循环状态OR结果保留起来【可以理解为程序没执行一次,就return 1,到迭代器里】,而return真的只有1次机会;
对比以下程序输出:
def inc1():
for i in range(5):
print inc1() #输出为0 也就是第一次
######################
def inc2():
for i in range(5):
for i in inc2():
print i #输出0 1 2 3 4
123456789101112
def inc1():&&&&for i in range(5):&&&&&&&&return i&print inc1() #输出为0 也就是第一次######################def inc2():&&&&for i in range(5):&&&&&&&&yield i&for i in inc2():&&&&print i #输出0 1 2 3 4
因为我们想要我们的Spider 不是像之前那样,只提取一次数据和只访问一次,最后通过列表返回Pipelines处理,但我们想要我们的蜘蛛执行N次提取结果,并执行N次Request请求“下一页”的网站链接,每次的items项目不同,每次Request的连接不同,这两个东西都需要迭代(item是必须的),scrapy早已考虑好该问题,设计的parse函数是可以返回除了item还有request,两个都是对象;说了这么多,我是想把下面程序说清楚
0x3 Spider功能实现:
from scrapy.spider import BaseSpider
from scrapy.selector import Selector
from tutorial.items import
TutorialItem
from scrapy.http import
Request #新增Request,注意大小写,请求页面;
class MutilPageSpider(BaseSpider): #编写新的蜘蛛
name="mutilpage"
allowed_domain=['drops.wooyun.org']
base_domain='drops.wooyun.org'
start_urls=["http://drops.wooyun.org/"]
parse(self, response): #告诉程序得到Response后怎么做
sel=Selector(response) #here get items
sites=sel.xpath('//h2[@class]')
#这里取消了,不用[]来返回所有列表元素了
for site in sites:
item=TutorialItem()
item['title']=site.xpath('a/text()').extract()[0]
item['href']=site.xpath('a/@href').extract()[0]
#items.append(item)
yield item #用yield把item存放到一个迭代器里,这个迭代比较好理解【每张页面的数据都在迭代器里】
# 下面查找下一页地址,并将URL放入Requst请求,回调parse来提取数据
for ur in sel.xpath("//div[@class='wp-pagenavi']/a[@class='nextpostslink']/@href").extract():#实际情况编写xpath提取规则
yield Request(ur,callback=self.parse)
#这里使用yield函数,第一反应,这不是数据,存放起来干什么,而且上面是个循环,那么这段不是可以执行所有的请求麼,为什么还要加上yield,
#但是,如果仔细分析,会发现上面的for ur in sel....,实际上该列表只有1个元素,而且是当前页面中“下一页”的链接,不用yield的情况下
#程序循环1次,那么request就执行一次,也就完事了,但是,,我们又想用这个函数来不停的请求下一页,而不想让函数“执行完毕后”跳出,
#没错,yield可以实现该Request函数并不执行完毕,而当"下一页" 这个条件不存在的时候,Request才算执行完毕,
#简而言之,yield能阻止函数跳出,除非next()不能再执行,或者用条件来跳出该yield函数
12345678910111213141516171819202122232425262728293031
from scrapy.spider import BaseSpiderfrom scrapy.selector import Selectorfrom tutorial.items import&&TutorialItemfrom scrapy.http import&&Request #新增Request,注意大小写,请求页面;&class MutilPageSpider(BaseSpider): #编写新的蜘蛛&&&&name="mutilpage"&&&&allowed_domain=['drops.wooyun.org']&&&&base_domain='drops.wooyun.org'&&&&start_urls=["http://drops.wooyun.org/"]&&&&&def&&parse(self, response): #告诉程序得到Response后怎么做&&&&&&&&sel=Selector(response) #here get items&&&&&&&&sites=sel.xpath('//h2[@class]')&&&&&&&&#items=[]&&#这里取消了,不用[]来返回所有列表元素了&&&&&&&&for site in sites:&&&&&&&&&&&&item=TutorialItem()&&&&&&&&&&&&item['title']=site.xpath('a/text()').extract()[0]&&&&&&&&&&&&item['href']=site.xpath('a/@href').extract()[0]&&&&&&&&&&&&#items.append(item)&&&&&&&&&&&&yield item #用yield把item存放到一个迭代器里,这个迭代比较好理解【每张页面的数据都在迭代器里】&# 下面查找下一页地址,并将URL放入Requst请求,回调parse来提取数据&&&&&&&&for ur in sel.xpath("//div[@class='wp-pagenavi']/a[@class='nextpostslink']/@href").extract():#实际情况编写xpath提取规则&&&&&&&&&&&&yield Request(ur,callback=self.parse) &#这里使用yield函数,第一反应,这不是数据,存放起来干什么,而且上面是个循环,那么这段不是可以执行所有的请求麼,为什么还要加上yield,#但是,如果仔细分析,会发现上面的for ur in sel....,实际上该列表只有1个元素,而且是当前页面中“下一页”的链接,不用yield的情况下#程序循环1次,那么request就执行一次,也就完事了,但是,,我们又想用这个函数来不停的请求下一页,而不想让函数“执行完毕后”跳出,#没错,yield可以实现该Request函数并不执行完毕,而当"下一页" 这个条件不存在的时候,Request才算执行完毕,#简而言之,yield能阻止函数跳出,除非next()不能再执行,或者用条件来跳出该yield函数
0x4 运行结果
可以采用json文件或者mysql管道处理类,来将程序抓取到的所有连接和标题存入json文件或者mysql,从debug窗口可以看到是350个item
运行命令 scrapy crawl mutilpage 查看生成文件随笔 - 849&
评论 - 67&
&&&&&&&&&&&
请初学者作为参考,不建议高手看这个浪费时间】
前两篇大概讲述了scrapy的安装及工作流程。这篇文章主要以一个实例来介绍scrapy的开发流程,本想以教程自带的dirbot作为例子,但感觉大家应该最先都尝试过这个示例,应该都很熟悉,这里不赘述,所以,将用笔者自己第一个较为完整的抓取程序作为示例作为讲解。
首先,要大规模抓取一个网站的内容,必要的资源便是代理ip这一资源,如果不使用代理ip,又追求抓取的速度,很可能会被被抓网站发现行踪并封掉抓取机,所以抓取大量可用的代理ip便是我们第一个任务。
大概这个爬虫要实现以下三个功能:
1. 抓取代理ip,端口信息
2. 验证代理ip,判断其透明性
3. 将可用的代理ip持久化到文件中以供后续抓取程序使用
&代理服务器网便是一个很好的代理ip的来源,简单看一下,共有12个页面,页面格式相同:
准备就绪,下面正式开始:
1. 定义item,根据需求,抓取的item最后应该包含如下信息才好用:
#前4个数据为页面可以直接获取的
#后三个数据为pipeline中后期得到的数据,很有用
所以定义代码如下:
1 # Define here the models for your scraped items
3 # See documentation in:
4 # http://doc.scrapy.org/topics/items.html
6 from scrapy.item import Item, Field
8 class ProxyItem(Item):
= Field() # 0: anonymity #1 nonanonymity
= Field() # in second
timestamp = Field()
2. 定义爬虫
爬虫中做的主要工作就是设置初始化urls,即【种子】,【可不是那种种子~是这种种子~】
然后在默认的parse函数中使用xpath可以轻松的获得所需要的字段,比如
addresses = hxs.select('//tr[position()&1]/td[position()=1]').re('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
可以获得ip信息的数组
locations = hxs.select('//tr[position()&1]/td[position()=4]').re('&td&(.*)&\/td&')
可以获得地理位置信息的数组
唯一有点麻烦的就是端口信息,网站站长可能想到数据会被抓取的可能,所以端口的输出使用了js输出,这确实增加了抓取的难度,scrapy和一般的爬虫是不具备浏览器的javascript解释器的,也不会执行这些js代码,所以,爬虫拿到的html代码中的端口号好没有被输出出来~
源码是这个样子
所以,一定在html的上部,会有这些&r&的定义,不难发现
经过几次刷新,发现这些定义并不是动态的,所以就简单些,直接拿到代码中的+r+d+r+d信息,将+号替换为空,将r替换成8,d替换成0即可,所以可以声明下边这样的一个map
port_map = {'z':'3','m':'4','k':'2','l':'9','d':'0','b':'5','i':'7','w':'6','r':'8','c':'1','+':''}
具体的爬虫代码如下
1 from scrapy.contrib.spiders import CrawlSpider, Rule
2 from scrapy.selector import HtmlXPathSelector
3 from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
4 from proxy.items import ProxyItem
5 import re
7 class ProxycrawlerSpider(CrawlSpider):
name = 'cnproxy'
allowed_domains = ['']
= [1,2,3,4,5,6,7,8,9,10]
start_urls = []
for i in indexes:
url = '/proxy%s.html' % i
start_urls.append(url)
start_urls.append('/proxyedu1.html')
start_urls.append('/proxyedu2.html')
def parse(self, response):
hxs = HtmlXPathSelector(response)
addresses = hxs.select('//tr[position()&1]/td[position()=1]').re('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
protocols = hxs.select('//tr[position()&1]/td[position()=2]').re('&td&(.*)&\/td&')
locations = hxs.select('//tr[position()&1]/td[position()=4]').re('&td&(.*)&\/td&')
= re.compile('write\(":"(.*)\)')
raw_ports = ports_re.findall(response.body);
port_map = {'z':'3','m':'4','k':'2','l':'9','d':'0','b':'5','i':'7','w':'6','r':'8','c':'1','+':''}
for port in raw_ports:
tmp = port
in port_map:
tmp = tmp.replace(key, port_map[key]);
ports.append(tmp)
items = []
for i in range(len(addresses)):
item = ProxyItem()
item['address']
= addresses[i]
item['protocol'] = protocols[i]
item['location'] = locations[i]
item['port']
= ports[i]
items.append(item)
return items
3. 执行pipeline,过滤并检查抓取到的代理ip,并将其持久化到文件中
一般性的校验过程我就不赘述了,直接介绍如果验证代理可用性及透明性的方法。
这需要另一个cgi程序的帮助。简单来说一个代理是否透明,就是在做中转的时候是否会将源ip放到请求包中并能够被被抓取方获取,如果能,就说明这个代理不是透明的,使用的时候就要多留意。
一般非透明代理ip会将源ip放到HTTP_X_FORWARDED_FOR字段中,为了更严谨些,另一个cgi脚本将服务器能获取到的所有跟ip有关的数据echo出来,php代码如下:
echo "PROXYDETECTATION&/br&";
echo "REMOTE_ADDR&/br&";
var_dump($_SERVER['REMOTE_ADDR']);
echo "&/br&";
echo "env_REMOTE_ADDR&/br&";
var_dump(getenv('REMOTE_ADDR'));
echo "&/br&";
echo "env_HTTP_CLIENT_IP&/br&";
var_dump(getenv('HTTP_CLIENT_IP'));
echo "&/br&";
echo "HTTP_CLIENT_IP&/br&";
var_dump($_SERVER['HTTP_CLIENT_IP']);
echo "&/br&";
echo "HTTP_X_FORWARDED_FOR&/br&";
var_dump($_SERVER['HTTP_X_FORWARDED_FOR']);
echo "&/br&";
echo "HTTP_X_FORWARDED&/br&";
var_dump($_SERVER['HTTP_X_FORWARDED']);
echo "&/br&";
echo "HTTP_X_CLUSTER_CLIENT_IP&/br&";
var_dump($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']);
echo "&/br&";
echo "HTTP_FORWARDED_FOR&/br&";
var_dump($_SERVER['HTTP_FORWARDED_FOR']);
echo "&/br&";
echo "HTTP_FORWARDED&/br&";
var_dump($_SERVER['HTTP_FORWARDED']);
echo "&/br&";
假设这个服务地址为
那么pipelines的代码如下
1 # Define your item pipelines here
2 # Don't forget to add your pipeline to the ITEM_PIPELINES setting
3 # See: http://doc.scrapy.org/topics/item-pipeline.html
4 from scrapy.exceptions import DropItem
5 import re
6 import urllib
7 import urllib2
8 import time
9 import exceptions
10 import socket
11 class ProxyPipeline(object):
def process_item(self, item, spider):
port = item['port']
port_re = re.compile('\d{1,5}')
= port_re.findall(port)
if len(ports) == 0:
raise DropItem("can not find port in %s" % item['port'])
item['port'] = ports[0]
#profiling the proxy
#detect_service_url = 'http://xxx.xxx.xxx.xxx:pppp/apps/proxydetect.php'
detect_service_url = 'http://xxx.xxx.xxx.xxx/apps/proxydetect.php'
= 'xxx.xxx.xxx.xxx'
= str('http://%s:%s' % (str(item['address']), str(item['port'])))
proxies = {'http':proxy_}
begin_time = time.time()
timeout = 1
socket.setdefaulttimeout(timeout)
= urllib.urlopen(detect_service_url, proxies=proxies).read()
except exceptions.IOError:
raise DropItem("curl download the proxy %s:%s is bad" % (item['address'],str(item['port'])))
= time.time()
if '' == data.strip():
raise DropItem("data is null the proxy %s:%s is bad" % (item['address'],str(item['port'])))
if data.find('PROXYDETECTATION') == -1:
raise DropItem("wrong response the proxy %s:%s is bad" % (item['address'],str(item['port'])))
if data.find('PROXYDETECTATION') != -1:
if data.find(local_ip) == -1:
item['type'] = 'anonymity'
item['type'] = 'nonanonymity'
item['delay'] = str(end_time - begin_time)
item['timestamp'] = time.strftime('%Y-%m-%d',time.localtime(time.time()))
#record the item info
= open('/home/xxx/services_runenv/crawlers/proxy/proxy/data/proxies.txt','a')
line = str(item['timestamp']) + '\t' + str(item['address']) + '\t' + str(item['port']) + '\t' + item['type'] + '\t' + str(item['delay']) + '\n'
fp.write(line)
fp.close()
return item
其中local_ip为抓取服务器本机的ip地址
4. 最后一个要说的就是setting.py配置文件,大家看具体代码吧
1 # Scrapy settings for proxy project
3 # For simplicity, this file contains only the most important settings by
4 # default. All the other settings are documented here:
http://doc.scrapy.org/topics/settings.html
9 BOT_NAME = 'proxy'
10 BOT_VERSION = '1.0'
12 SPIDER_MODULES = ['proxy.spiders']
13 NEWSPIDER_MODULE = 'proxy.spiders'
14 USER_AGENT = '%s/%s' % (BOT_NAME, BOT_VERSION)
16 DOWNLOAD_DELAY = 0
17 DOWNLOAD_TIMEOUT = 30
19 ITEM_PIPELINES = [
'proxy.pipelines.ProxyPipeline'
22 CONCURRENT_ITEMS = 100
23 CONCURRENT_REQUESTS_PER_SPIDER = 64
24 CONCURRENT_SPIDERS = 128
26 LOG_ENABLED = True
27 LOG_ENCODING = 'utf-8'
28 LOG_FILE = '/home/xxx/services_runenv/crawlers/proxy/proxy/log/proxy.log'
29 LOG_LEVEL = 'DEBUG'
30 LOG_STDOUT = False
最后秀一下抓取到的代理ip数据
好了,这篇就这些,下一篇将介绍如果使用代理ip作为媒介,放心的去大规模抓取网站数据,晚安。
喜欢一起简单,实用的东西,拒绝复杂花哨,我不是GEEK.
阅读(...) 评论()406 Not Acceptable
406 Not Acceptable
ASERVER/1.2.9-3Scrapy 概览 & scrapy 0.15.1 documentation
Navigation
Scrapy 概览
Scrapy 是一款抓取网页并从中提取结构化数据的应用程序框架,它具有非常广泛的应用场景,如:数据挖掘、信息处理和历史信息归档等。
尽管 Scrapy 最初被设计用于(准确地说是),但您也可以仅使用它的 API 来提取数据(就像 )或作为通用的网页爬虫来使用。
本文档的目的是向您介绍概念背后的 Scrapy,这样您才能知道它是如何工作的,以及决定 Scrapy 是否满足您的需要。
当您已经准备好要开始一个项目时,请直接阅读此。
选择一个网站
现在,您要从一个网站上提取一些您所需要的信息,但是这些网站又未提供任何机制或 API 让您的程序可以访问这些信息。此时,Scrapy 可以轻松地帮您完成这项工作。
比方说,现在我们要提取 Mininova 网站上,今日新增的种子文件的 URL、name、description 和 size 等数据。
这些新增的种子文件的列表,可以从下面的地址中找到:
定义您要抓取的数据
在开始抓取之前,我们必须先定义我们要抓取的数据。对于 Scrapy 来说,是由
来实现的(在我们的例子中就是种子文件)。
这就是本例中我们需要的 Item 的样子:
from scrapy.item import Item, Field
class Torrent(Item):
url = Field()
name = Field()
description = Field()
size = Field()
编写 Spider 来提取数据
接下来,我们要编写一个 Spider ,为之前提到的那个 URL() 定义抓取和从该页面提取数据的规则。
如果我们看一下这个页面的内容,我们会发现,所有种子文件的 URL 都类似于这样:http://www.mininova.org/tor/NUMBER,其中 NUMBER 是一个整数。我们将利用这一规则来构造一个正则表达式:/tor/\d+。
我们将使用
来提取目标网页 HTML 源码中我们所需要的数据。现在,让我们从这些种子文件列表中选取一个出来:
然后查看这个页面的 HTML 源码,找到我们需要的数据(种子文件的name、description以及size)并构造出相应的 XPath。
通过查看页面的 HTML 源码,我们可以看到,种子文件的 name 被包含在 &h1& 标签中:
&h1&Home[2009][Eng]XviD-ovd&/h1&
那么,一个提取该名称的 XPath 表达式就出来了(这只是其中一个可能,提取同一个数据,可能会有多种不同写法的 XPath):
//h1/text()
description 被包含在一个
id=&description& 的 &div& 标签中:
&h2&Description:&/h2&
&div id=&description&&
&HOME& - a documentary film by Yann Arthus-Bertrand
&We are living in exceptional times. Scientists tell us that we have 10 years to change the way we live, avert the depletion of natural resources and the catastrophic evolution of the Earth's climate.
一种可能地提取 description 的 XPath 表达式为:
//div[@id='description']
最后,种子文件的 size 被包含在一个 id=specifications 的 &div& 标签中的 &p& 标签中:
&div id=&specifications&&
&strong&Category:&/strong&
&a href=&/cat/4&&Movies&/a& & &a href=&/sub/35&&Documentary&/a&
&strong&Total size:&/strong&
699.79&megabyte&/p&
一种可能地提取 size 的 XPath 表达式为:
//div[@id='specifications']/p[2]/text()[2]
有关 XPath 的更多信息,见 。
以下是我们 Spider 的最终代码:
class MininovaSpider(CrawlSpider):
name = 'mininova.org'
allowed_domains = ['mininova.org']
start_urls = ['http://www.mininova.org/today']
rules = [Rule(SgmlLinkExtractor(allow=['/tor/\d+']), 'parse_torrent')]
def parse_torrent(self, response):
x = HtmlXPathSelector(response)
torrent = TorrentItem()
torrent['url'] = response.url
torrent['name'] = x.select(&//h1/text()&).extract()
torrent['description'] = x.select(&//div[@id='description']&).extract()
torrent['size'] = x.select(&//div[@id='info-left']/p[2]/text()[2]&).extract()
return torrent
为了简洁起见,我们故意省略了 import 语句。代码中的 TorrentItem 见。
运行 Spider 提取数据
最后,我们将运行这个 Spider 来抓取 Mininova 站点的信息,把抓取的数据以 JSON 格式保存到 scraped_data.json 文件中:
scrapy crawl mininova.org -o scraped_data.json -t json
这是使用的
来生成 JSON 文件。
您可以很方便的改变导出文件的格式(例如:XML 或 CSV)或存储后端(例如:FTP 或 )。
另外,你还能编写
将提取的数据(本例中的 TorrentItem)保存到数据库中,这一切都非常简单。
检查抓取的数据
如果您在 Spider 处理完成后查阅 scraped_data.json 文件,您将在该文件中看到抓取的数据(本例中的 TorrentItem):
[{&url&: &http://www.mininova.org/tor/2657665&, &name&: [&Home[2009][Eng]XviD-ovd&], &description&: [&HOME - a documentary film by ...&], &size&: [&699.69 megabyte&]},
# ... other items ...
您将发现所有的字段值(除了 url 被直接分配)实际上都是列表。这是因为返回列表。您可能想存储单个的值,或经过额外处理后的值,请查阅Item Loaders &topics-loaders&。
还有别的吗?
您已经看到如何利用 Scrapy 从一个网页中提取和存储数据了,但这不过是 Scrapy 的冰山一角而已。Scrapy 提供了许多强大的功能让网页抓取变得更加容易和高效,比如:
内建支持从 HTML 和 XML 源码中数据。
内建支持使用可重用的过滤器集合(被称为 )对抓取数据进行额外地处理,这些过滤器能够被所有的 Spider 共享使用。
内建支持将抓取数据到多种格式(JSON,CSV,XML)的文件和不同的存储后端(FTP,S3,本地文件系统)中。
可以在相关项目中使用 Media Pipeline(如:ImagePipeline)或其它的媒体文件。
利用和定义良好的 API(Middlewares,
和 )来添加您自己的功能,从而进一步。
完善的内建 Middlewares 和 Extensions:
Cookies 和 Session 处理
user-agent 伪装
robots.txt
抓取深度限制
强大的编码支持与自动检测,能够处理陌生的(foreign)、非标准的以及错误(broken)的编码声明。
可扩展的用于收集多个 Spider 的运行指标,这在监控 Spider 的性能以及检测 Spider 是否正常工作时非常有用。
使用测试 XPath,这在编写和调试 Spider 时非常有用。
内建的旨在简化您的 Spider 在生产环境中的部署和运行。
用于监测和控制您的机器人(bot)。
内建的 可以在您的 Scrapy 进程中挂接运行一个 Python 控制台,来检查和调试您的网页抓取服务。
功能使您能够查看在抓取进程运行期间捕获的错误。
的 URL 的抓取。
缓存 DNS 解析。
接下来做什么?
很明显,接下来您需要,阅读以及加入。感谢您对 Scrapy 感兴趣。
Navigation首先,我们定义一下定向抓取,定向抓取是一种特定的抓取需求,目标站点是已知的,站点的页面是已知的。本文的介绍里面,主要是侧重于如何快速构建一个实时的抓取系统,并不包含通用意义上的比如链接分析,站点发现等等特性。
在本文提到的实例系统里面,主要用到
linux+mysql+redis+django+scrapy+webkit,其中scrapy+webkit作为抓取端,redis作为链接库存
储,mysql作为网页信息存储,django作为爬虫管理界面,快速实现分布式抓取系统的原型。
名词解析:
1. &抓取环:抓取环指的是spider在存储中获取url,从互联网上下载网页,然后将网页存储到数据库里面,最后在从存储里面获取下一个URL的一个流程。
2. &Linkbase:链接库的存储模块,包含一般的链接信息;是抓取系统的核心,使用redis存储。
3. &:一门在 XML 文档中查找信息的语言,XPath 可用来在 XML 文档中对元素和属性进行遍历, 是 W3C XSLT 标准的主要元素。使用XPATH以及相关工具lib进行链接抽取和信息抽取。
4. &XPathOnClick:一个chrome的插件,支持点击页面元素,获取XPATH路径,用于编辑配置模板。
5. &:一个开源的KV的内存数据库,具备很好的数据结构的特征和很高的存取性能。用于存储linkbase信息
6. &:爬虫管理工具,用于模板配置,系统监控反馈。Django在这里主要是用来管理一个数据库,使用Admin功能。
7. & Pagebase:页面库,主要是存储网页抓取的结果,以及页面抽取的结果,和dump交互,使用mysql实现。
8. & &:一个开源的机遇twisted框架的python的单机爬虫,该爬虫实际上包含大多数网页抓取的工具包,用于爬虫下载端以及抽取端。
9.&&&& 列表页:指的商品页面之外的所有页面
10. & &详情页:比如商品B2C的抓取中,特指商品页面,比如
日期:November 06 , 2012 &|&
分类: &|&
评论: &|&
标签:& & &

我要回帖

更多关于 python scrapy 的文章

 

随机推荐