如何在Scrapy的parse()功能中获取请求URL ?我有很多网址start_urls,其中一些将我的蜘蛛重定向到主页,结果我有一个空项目.所以我需要item['start_url'] = request.url存储这些网址的东西.我正在使用BaseSpider.
我已经使用scrapy编写了一个正在运行的爬虫,
现在我想通过Django webapp来控制它,也就是说:
start_urlsallowed_domainssettings值起初我认为scrapyd是为此而制作的,但在阅读了文档之后,似乎它更像是一个能够管理"打包蜘蛛"的守护进程,也就是"scrapy eggs"; 并且所有的设置(start_urls,allowed_domains,settings)仍必须在"scrapy鸡蛋"本身硬编码; 所以它看起来不像我的问题的解决方案,除非我错过了什么.
我还看了这个问题:如何为scrapy提供URL以进行爬行?; 但提供多个网址的最佳答案是由作者himeslf认定为"丑陋的黑客",涉及一些python子进程和复杂的shell处理,所以我认为这里找不到解决方案.此外,它可能适用start_urls,但它似乎不允许allowed_domains或settings.
然后我看了scrapy webservices:它似乎是检索统计数据的好方法.但是,它仍然需要一个正在运行的蜘蛛,并且没有改变的线索settings
关于这个问题有几个问题,似乎没有一个问题令人满意:
我知道scrapy用于生产环境; 像scrapyd这样的工具表明,确实有一些方法可以满足这些要求(我无法想象用于处理的scrapy egg scrap是手工生成的!)
非常感谢你的帮助.
我正在阅读scrapy教程http://doc.scrapy.org/en/latest/intro/tutorial.html ,我一直跟着它直到我运行这个命令
scrapy crawl dmoz
Run Code Online (Sandbox Code Playgroud)
它给了我输出错误
2013-08-25 13:11:42-0700 [scrapy] INFO: Scrapy 0.18.0 started (bot: tutorial)
2013-08-25 13:11:42-0700 [scrapy] DEBUG: Optional features available: ssl, http11
2013-08-25 13:11:42-0700 [scrapy] DEBUG: Overridden settings: {'NEWSPIDER_MODULE': 'tutorial.spiders', 'SPIDER_MODULES': ['tutorial.spiders'], 'BOT_NAME': 'tutorial'}
2013-08-25 13:11:42-0700 [scrapy] DEBUG: Enabled extensions: LogStats, TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState
Traceback (most recent call last):
File "/usr/local/bin/scrapy", line 4, in <module>
execute()
File "/Library/Python/2.7/site-packages/scrapy/cmdline.py", line 143, in execute
_run_print_help(parser, _run_command, cmd, args, opts)
File "/Library/Python/2.7/site-packages/scrapy/cmdline.py", line 88, in _run_print_help
func(*a, **kw) …Run Code Online (Sandbox Code Playgroud) 我的蜘蛛有一个严重的内存泄漏..运行15分钟后,它的内存5gb和scrapy告诉(使用prefs())有900k请求对象,那就是全部.这么多生活请求对象的原因是什么?请求只会上升并且不会下降.所有其他对象都接近于零.
我的蜘蛛看起来像这样:
class ExternalLinkSpider(CrawlSpider):
name = 'external_link_spider'
allowed_domains = ['']
start_urls = ['']
rules = (Rule(LxmlLinkExtractor(allow=()), callback='parse_obj', follow=True),)
def parse_obj(self, response):
if not isinstance(response, HtmlResponse):
return
for link in LxmlLinkExtractor(allow=(), deny=self.allowed_domains).extract_links(response):
if not link.nofollow:
yield LinkCrawlItem(domain=link.url)
Run Code Online (Sandbox Code Playgroud)
这里输出prefs()
HtmlResponse 2 oldest: 0s ago
ExternalLinkSpider 1 oldest: 3285s ago
LinkCrawlItem 2 oldest: 0s ago
Request 1663405 oldest: 3284s ago
Run Code Online (Sandbox Code Playgroud)
在一些网站上,100k页面的内存可以达到40gb标记(例如,在victorinox.com上,在100k页面标记处达到35gb内存).在其他它更小.
UPD.
Scrapy非常酷,但我发现文档非常简单,一些简单的问题很难回答.在汇总各种堆栈溢出的各种技术之后,我终于提出了一种简单而不过度技术的方法来运行多个scrapy蜘蛛.我认为它的技术性不如试图实现scrapyd等:
所以这里有一只蜘蛛可以很好地完成这项工作,它可以在表单请求之后抓取一些数据:
from scrapy.spider import BaseSpider
from scrapy.selector import Selector
from scrapy.http import Request
from scrapy.http import FormRequest
from swim.items import SwimItem
class MySpider(BaseSpider):
name = "swimspider"
start_urls = ["swimming website"]
def parse(self, response):
return [FormRequest.from_response(response,formname="AForm",
formdata={"lowage": "20, "highage": "25"}
,callback=self.parse1,dont_click=True)]
def parse1(self, response):
#open_in_browser(response)
hxs = Selector(response)
rows = hxs.xpath(".//tr")
items = []
for rows in rows[4:54]:
item = SwimItem()
item["names"] = rows.xpath(".//td[2]/text()").extract()
item["age"] = rows.xpath(".//td[3]/text()").extract()
item["swimtime"] = rows.xpath(".//td[4]/text()").extract()
item["team"] = rows.xpath(".//td[6]/text()").extract()
items.append(item)
return items
Run Code Online (Sandbox Code Playgroud)
而不是刻意写出表格输入我想要的表格输入,即"20"和"25:
formdata={"lowage": "20", "highage": …Run Code Online (Sandbox Code Playgroud) 我正在使用scrapy进行一个项目,我想要刮掉一些网站 - 可能是数百个 - 我必须为每个网站编写一个特定的蜘蛛.我可以使用以下方法在部署到scrapyd的项目中安排一个蜘蛛:
curl http://localhost:6800/schedule.json -d project=myproject -d spider=spider2
Run Code Online (Sandbox Code Playgroud)
但是如何一次安排项目中的所有蜘蛛呢?
所有帮助非常感谢!
我使用单一的"硒 - scrapy杂交"蜘蛛运行报废1.1 + scrapy 0.24.6,根据参数爬行到许多领域.托管scrapyd实例(s?)的开发机器是一个具有4个内核的OSX Yosemite,这是我目前的配置:
[scrapyd]
max_proc_per_cpu = 75
debug = on
Run Code Online (Sandbox Code Playgroud)
报废开始时的输出:
2015-06-05 13:38:10-0500 [-] Log opened.
2015-06-05 13:38:10-0500 [-] twistd 15.0.0 (/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python 2.7.9) starting up.
2015-06-05 13:38:10-0500 [-] reactor class: twisted.internet.selectreactor.SelectReactor.
2015-06-05 13:38:10-0500 [-] Site starting on 6800
2015-06-05 13:38:10-0500 [-] Starting factory <twisted.web.server.Site instance at 0x104b91f38>
2015-06-05 13:38:10-0500 [Launcher] Scrapyd 1.0.1 started: max_proc=300, runner='scrapyd.runner'
Run Code Online (Sandbox Code Playgroud)
核心数量:
python -c 'import multiprocessing; print(multiprocessing.cpu_count())'
4
Run Code Online (Sandbox Code Playgroud)
我希望设置为单个蜘蛛同时处理300个作业,但无论有多少作业待处理,报废一次处理1到4个:

CPU使用率不是很大:

我还在Ubuntu 14.04 VM上测试了这个场景,结果大致相同:执行时最多运行5个作业,没有压倒性的CPU消耗,或多或少同时执行相同数量的任务.
scrapy doc说:
Scrapy附带一个名为"Scrapyd"的内置服务,允许您使用JSON Web服务部署(也称为.上传)您的项目并控制其蜘蛛.
使用报废有什么优势吗?
我创建了几个我打算与scrapyd同时运行的网络蜘蛛.我首先使用以下命令在Ubuntu 14.04中成功安装了scrapyd:pip install scrapyd,当我运行命令:scrapyd时,我在终端中得到以下输出:
2015-07-14 01:22:02-0400 [-] Log opened.
2015-07-14 01:22:02-0400 [-] twistd 13.2.0 (/usr/bin/python 2.7.6) starting up.
2015-07-14 01:22:02-0400 [-] reactor class: twisted.internet.epollreactor.EPollReactor.
2015-07-14 01:22:02-0400 [-] Site starting on 6800
2015-07-14 01:22:02-0400 [-] Starting factory <twisted.web.server.Site instance at 0x7f762f4391b8>
2015-07-14 01:22:02-0400 [Launcher] Scrapyd 1.1.0 started: max_proc=8, runner='scrapyd.runner'
Run Code Online (Sandbox Code Playgroud)
我相信我得到这个输出的事实表明scrapy正在发挥作用; 然而,当我运行命令:scrapyd部署作为文档,我得到的错误:scrapyd部署:命令未找到.如果安装成功,这怎么可能?我在配置文件中包含以下目标:
[deploy:scrapyd2]
url = http://scrapyd.mydomain.com/api/scrapyd/
username = name
password = secret
Run Code Online (Sandbox Code Playgroud)
我不确定目标是如何工作的,但我基本上是从文档中复制它,所以我认为它会起作用.有没有我应该导入或配置的东西,我没有?谢谢.