- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我使用 Scrapy 抓取网页并下载一些文件。由于我得到的file_url会重定向到另一个url(302重定向)。所以我使用另一种方法handle_redirect来获取重定向的url。我像这样自定义文件管道。
class MyFilesPipeline(FilesPipeline):
def handle_redirect(self, file_url):
response = requests.head(file_url)
if response.status_code == 302:
file_url = response.headers["Location"]
return file_url
def get_media_requests(self, item, info):
redirect_url = self.handle_redirect(item["file_urls"][0])
yield scrapy.Request(redirect_url)
def item_completed(self, results, item, info):
file_paths = [x['path'] for ok, x in results if ok]
if not file_paths:
raise DropItem("Item contains no images")
item['file_urls'] = file_paths
return item
通过上面的代码,我可以下载文件,但是下载的过程是阻塞的,所以整个项目变得很慢。
我在 spider 中尝试了另一种解决方案,首先使用 Requests 获取重定向的 url,然后传递给另一个函数。并使用默认的文件管道。
yield scrapy.Request(
download_url[0],
meta={
"name": name,
},
dont_filter=True,
callback=self.handle_redirect)
def handle_redirect(self, response):
logging.warning("respon %s" % response.meta)
download_url = response.headers["Location"].decode("utf-8")
return AppListItem(
name=response.meta["name"],
file_urls=[download_url],
)
还是阻塞进程。
从这里开始
When the item reaches the FilesPipeline, the URLs in the file_urls field are scheduled for download using the standard Scrapy scheduler and downloader (which means the scheduler and downloader middlewares are reused), but with a higher priority, processing them before other pages are scraped. The item remains “locked” at that particular pipeline stage until the files have finish downloading (or fail for some reason)
这是否意味着在文件下载之前我不能抓取下一个 url?(我没有在我的设置中设置 download_delay)
我一开始已经添加了这个:
handle_httpstatus_list = [302]
所以我不会被重定向到重定向的 url,我的第一个解决方案使用 requests 是因为我认为 yield 会像这样工作:
或者我必须等待下载文件才能抓取下一页?这是Scrapy的缺点吗?第二部分我没有遵循的是如何计算抓取页面的速度。例如,3s 一个完整的页面,默认并发为 16。我猜 @neverlastn 使用 16/2/3 来获得 2.5 页/s.并发16不就是可以同时处理16个请求吗?那么速度应该是16页/秒?如果我错了,请指正。
谢谢你的回答,我现在明白怎么计算了,但是我还是不明白第二部分。在302上我第一次遇到这个问题。 Error 302 Downloading File in Scrapy我有一个像这样的网址
http://example.com/first
这将使用 302 并重定向到
http://example.com/second
但是Scrapy不会自动重定向到第二个,也无法下载有线的文件。来自此处的代码 Scrapy-redirect并在这里做RedirectMiddleware指出 scrapy 应该默认处理重定向。这就是为什么我做了一些技巧并试图修复它。我的第三个解决方案将尝试使用 Celery像这样
class MyFilesPipeline(FilesPipeline):
@app.task
def handle_redirect(self, file_url):
response = requests.head(file_url)
if response.status_code == 302:
file_url = response.headers["Location"]
return file_url
def get_media_requests(self, item, info):
redirect_url = self.handle_redirect.delay(item["file_urls"][0])
yield scrapy.Request(redirect_url)
def item_completed(self, results, item, info):
file_paths = [x['path'] for ok, x in results if ok]
if not file_paths:
raise DropItem("Item contains no images")
item['file_urls'] = file_paths
return item
因为我已经有很多蜘蛛,所以我不想使用第二种解决方案来覆盖它们。所以我在管道中处理它们,这个解决方案会更好吗?
最佳答案
您使用 requests
同步/阻塞的API。这意味着您将并发数 ( CONCURRENT_REQUESTS_PER_DOMAIN
) 从(默认情况下)8 变为有效的 1。它似乎主宰了你的延迟。你在第二次尝试时做的那个技巧不错。这不使用 requests
因此它应该比使用 requests
更快(不是吗?)现在,当然你会增加额外的延迟......如果你的第一个(HTML)请求需要 1s 而第二个(图像)请求需要 2s,那么整个页面你有 3s。默认并发数为 16,这意味着您将以大约 2.5 页/秒的速度爬行。当您的重定向失败并且您没有抓取图像时,该过程将花费大约。 1s 即 8 页/秒。所以你可能会看到 3 倍的减速。一种解决方案可能是通过增加 CONCURRENT_REQUESTS_PER_DOMAIN
将允许并行运行的并发请求数增加 3 倍。和/或 CONCURRENT_REQUESTS
.如果您现在从带宽有限和/或延迟增加的地方运行它,另一种解决方案可能是从靠近图像服务器托管区域(例如 EC2 美国东部)的云服务器运行它。
编辑
性能用“小定律”更好理解。第一两个CONCURRENT_REQUESTS_PER_DOMAIN
和 CONCURRENT_REQUESTS
通常并行工作。 CONCURRENT_REQUESTS_PER_DOMAIN
= 8 默认情况下,我猜你通常从单个域下载,因此你的实际并发限制是 8。并发级别(即 8)不是每秒,而是一个固定数字,就像说“那个 toastr 可以在其中最多烘烤 8 个羊角面包”。您的羊角面包烘烤的速度有多快是延迟(这是网络响应时间),您感兴趣的指标是它们的比率,即 8 个羊角面包可以并行烘烤/每个羊角面包 3 秒 = 我将烘烤 2.5 个羊角面包/秒。
关于 302,我不确定你到底想做什么。我认为您只是在关注它们 - 只是您手动进行。我认为 scrapy 会在扩展允许的代码时为你做这件事。 FilesPipeline
可能无法从 handle_httpstatus_list
中获取值但是全局设置 HTTPERROR_ALLOWED_CODES
应该会影响 FilesPipeline
无论如何,requests
是一个糟糕的选择,因为它阻塞 = 绝对是非常糟糕的性能。 yield
ing Scrapy Request
s 将“让他们离开”(现在),但您将再次“遇到他们”,因为他们使用相同的资源、调度程序和下载程序来进行实际下载。这意味着它们很可能会降低您的性能……这是一件好事。我知道您在这里需要快速爬行,但 scrapy 希望您意识到自己在做什么以及何时设置并发限制,例如8 或 16,您相信 scrapy 不会以高于该速率的速率“淹没”您的目标站点。 Scrapy 会采取悲观的假设,即由同一服务器/域提供的媒体文件是到其 Web 服务器(而不是某些 CDN)的流量,并将应用相同的限制以保护目标站点和您。否则,想象一个页面恰好有 1000 张图片。如果您以某种方式“免费”获得了 1000 次下载,您将并行向服务器发出 8000 次请求,并发设置为 8 - 这不是一件好事。
如果您想“免费”获得一些下载,即不遵守并发限制的下载,您可以使用 treq .这是 Twisted 框架的请求包。 Here介绍如何在管道中使用它。使用它来访问我拥有的 API 或 Web 服务器,而不是第 3 方服务器,我会感觉更舒服。
关于python - 下载文件时 Scrapy i/o block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38800942/
在一个 scrapy 项目中,人们经常使用中间件。在交互式 session 期间是否也有一种通用方法可以在 scrapy shell 中启用中间件? 最佳答案 尽管如此,在 setting.py 中设
我想对网页中向下滚动生成的内容进行反向工程。问题出在url https://www.crowdfunder.com/user/following_page/80159?user_id=80159&li
我需要帮助将相对URL转换为Scrapy Spider中的绝对URL。 我需要将起始页面上的链接转换为绝对URL,以获取起始页面上已草稿的项目的图像。我尝试使用不同的方法来实现此目标失败,但是我陷入了
我在 Scrapy Python 中制作了一个脚本,它在几个月内一直运行良好(没有更改)。最近,当我在 Windows Powershell 中执行脚本时,它引发了下一个错误: scrapy craw
我已经从 docker 启动了 splash。我为 splash 和 scrapy 创建了大的 lua 脚本,然后它运行我看到了问题: Lua error: error in __gc metamet
我正在使用scrapy 来抓取网站,但发生了不好的事情(断电等)。 我想知道我怎样才能从它坏了的地方继续爬行。我不想从种子开始。 最佳答案 这可以通过将预定的请求持久化到磁盘来完成。 scrapy c
有人可以向我解释一下 Scrapy 中的暂停/恢复功能是如何实现的吗?作品? scrapy的版本我正在使用的是 0.24.5 documentation没有提供太多细节。 我有以下简单的蜘蛛: cla
我想将 apscheduler 与 scrapy.but 我的代码是错误的。 我应该如何修改它? settings = get_project_settings() configure_logging
我正在抓取一个网站并解析一些内容和图像,但即使对于 100 页左右的简单网站,完成这项工作也需要数小时。我正在使用以下设置。任何帮助将不胜感激。我已经看过这个问题- Scrapy 's Scrapyd
我正在抓取一个网站并解析一些内容和图像,但即使对于 100 页左右的简单网站,完成这项工作也需要数小时。我正在使用以下设置。任何帮助将不胜感激。我已经看过这个问题- Scrapy 's Scrapyd
我是爬行新手,想知道是否可以使用 Scrapy 逐步爬行网站,例如 CNBC.com?例如,如果今天我从一个站点抓取所有页面,那么从明天开始我只想收集新发布到该站点的页面,以避免抓取所有旧页面。 感谢
我是scrapy的新手。我正在尝试从 here 下载图像.我在关注 Official-Doc和 this article . 我的 settings.py 看起来像: BOT_NAME = 'shop
我在使用 scrapy 时遇到了一些问题。它没有返回任何结果。我试图将以下蜘蛛复制并粘贴到 scrapy shell 中,它确实有效。真的不确定问题出在哪里,但是当我用“scrapy crawl rx
如何使用 Scrapy 抓取多个 URL? 我是否被迫制作多个爬虫? class TravelSpider(BaseSpider): name = "speedy" allowed_d
当我使用splash渲染整个目标页面来爬取整个网站时出现问题。某些页面不是随机成功的,所以我错误地获取了支持渲染工作完成后出现的信息。这意味着我尽管我可以从其他渲染结果中获取全部信息,但仅从渲染结果中
如何使用 Scrapy 抓取多个 URL? 我是否被迫制作多个爬虫? class TravelSpider(BaseSpider): name = "speedy" allowed_d
我的scrapy程序无论如何只使用一个CPU内核CONCURRENT_REQUESTS我做。 scrapy中的某些方法是否可以在一个scrapy爬虫中使用所有cpu核心? ps:好像有争论max_pr
我最近用 python 和 Selenium 做了一个网络爬虫,我发现它做起来非常简单。该页面使用 ajax 调用来加载数据,最初我等待固定的 time_out 来加载页面。这工作了一段时间。之后,我
我想用这个命令运行 scrapy 服务器: scrapy server 它失败了,因为没有项目。然后我创建一个空项目来运行服务器,并成功部署另一个项目。但是,scrapy 服务器无法处理这个项目,并告
我正在创建一个网络应用程序,用于从不同网站抓取一长串鞋子。这是我的两个单独的 scrapy 脚本: http://store.nike.com/us/en_us/pw/mens-clearance-s
我是一名优秀的程序员,十分优秀!