- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
背景 - TLDR:我的项目内存泄漏
花了几天时间用scrapy查看内存泄漏文档,但找不到问题。
我正在开发一个中等规模的scrapy 项目,每天大约有 4 万个请求。
我使用scrapinghub的预定运行来主持这个。
在 scrapinghub ,每月 9 美元,您基本上可以获得 1 个具有 1GB RAM 的 VM 来运行您的爬虫。
我在本地开发了一个爬虫并上传到scrapinghub,唯一的问题是在运行结束时,我超出了内存。
本地化设置 CONCURRENT_REQUESTS=16
工作正常,但导致在 50% 点超过了 scrapinghub 上的内存。当我设置 CONCURRENT_REQUESTS=4
, 我在 95% 点超过了内存,所以减少到 2 应该可以解决问题,但是我的爬虫变得太慢了。
另一种解决方案是为 2 个 VM 付费以增加 RAM,但我有一种感觉,我设置爬网程序的方式会导致内存泄漏。
对于此示例,该项目将抓取在线零售商。
在本地运行时,我的 memusage/max
是 2.7GB,带有 CONCURRENT_REQUESTS=16
.
我现在将运行我的scrapy结构
class Pipeline(object):
def process_item(self, item, spider):
item['stock_jsons'] = json.loads(item['stock_jsons'])['subProducts']
return item
class mainItem(scrapy.Item):
date = scrapy.Field()
url = scrapy.Field()
active_col_num = scrapy.Field()
all_col_nums = scrapy.Field()
old_price = scrapy.Field()
current_price = scrapy.Field()
image_urls_full = scrapy.Field()
stock_jsons = scrapy.Field()
class URLItem(scrapy.Item):
urls = scrapy.Field()
class ProductSpider(scrapy.Spider):
name = 'product'
def __init__(self, **kwargs):
page = requests.get('www.example.com', headers=headers)
self.num_pages = # gets the number of pages to search
def start_requests(self):
for page in tqdm(range(1, self.num_pages+1)):
url = 'www.example.com/page={page}'
yield scrapy.Request(url = url, headers=headers, callback = self.prod_url)
def prod_url(self, response):
urls_item = URLItem()
extracted_urls = response.xpath(####).extract() # Gets URLs to follow
urls_item['urls'] = [# Get a list of urls]
for url in urls_item['urls']:
yield scrapy.Request(url = url, headers=headers, callback = self.parse)
def parse(self, response) # Parse the main product page
item = mainItem()
item['date'] = DATETIME_VAR
item['url'] = response.url
item['active_col_num'] = XXX
item['all_col_nums'] = XXX
item['old_price'] = XXX
item['current_price'] = XXX
item['image_urls_full'] = XXX
try:
new_url = 'www.exampleAPI.com/' + item['active_col_num']
except TypeError:
new_url = 'www.exampleAPI.com/{dummy_number}'
yield scrapy.Request(new_url, callback=self.parse_attr, meta={'item': item})
def parse_attr(self, response):
## This calls an API Step 5
item = response.meta['item']
item['stock_jsons'] = response.text
yield item
到目前为止我尝试过什么?
trackref.print_live_refs()
最后返回以下内容:HtmlResponse 31 oldest: 3s ago
mainItem 18 oldest: 5s ago
ProductSpider 1 oldest: 3321s ago
Request 43 oldest: 105s ago
Selector 16 oldest: 3s ago
2020-09-17 11:54:11 [scrapy.utils.log] INFO: Scrapy 2.3.0 started (bot: PLT)
2020-09-17 11:54:11 [scrapy.utils.log] INFO: Versions: lxml 4.5.2.0, libxml2 2.9.10, cssselect 1.1.0, parsel 1.6.0, w3lib 1.22.0, Twisted 20.3.0, Python 3.7.4 (v3.7.4:e09359112e, Jul 8 2019, 14:54:52) - [Clang 6.0 (clang-600.0.57)], pyOpenSSL 19.1.0 (OpenSSL 1.1.1g 21 Apr 2020), cryptography 3.1, Platform Darwin-18.7.0-x86_64-i386-64bit
2020-09-17 11:54:11 [scrapy.crawler] INFO: Overridden settings:
{'BOT_NAME': 'PLT',
'CONCURRENT_REQUESTS': 14,
'CONCURRENT_REQUESTS_PER_DOMAIN': 14,
'DOWNLOAD_DELAY': 0.05,
'LOG_LEVEL': 'INFO',
'NEWSPIDER_MODULE': 'PLT.spiders',
'SPIDER_MODULES': ['PLT.spiders']}
2020-09-17 11:54:11 [scrapy.extensions.telnet] INFO: Telnet Password: # blocked
2020-09-17 11:54:11 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.corestats.CoreStats',
'scrapy.extensions.telnet.TelnetConsole',
'scrapy.extensions.memusage.MemoryUsage',
'scrapy.extensions.logstats.LogStats']
2020-09-17 11:54:12 [scrapy.middleware] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
'scrapy.downloadermiddlewares.retry.RetryMiddleware',
'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware',
'scrapy.downloadermiddlewares.stats.DownloaderStats']
2020-09-17 11:54:12 [scrapy.middleware] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',
'scrapy.spidermiddlewares.referer.RefererMiddleware',
'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
'scrapy.spidermiddlewares.depth.DepthMiddleware']
=======
17_Sep_2020_11_54_12
=======
2020-09-17 11:54:12 [scrapy.middleware] INFO: Enabled item pipelines:
['PLT.pipelines.PltPipeline']
2020-09-17 11:54:12 [scrapy.core.engine] INFO: Spider opened
2.结束日志行(信息:Dumping Scrapy stats to end)。
2020-09-17 11:16:43 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 15842233,
'downloader/request_count': 42031,
'downloader/request_method_count/GET': 42031,
'downloader/response_bytes': 1108804016,
'downloader/response_count': 42031,
'downloader/response_status_count/200': 41999,
'downloader/response_status_count/403': 9,
'downloader/response_status_count/404': 1,
'downloader/response_status_count/504': 22,
'dupefilter/filtered': 110,
'elapsed_time_seconds': 3325.171148,
'finish_reason': 'finished',
'finish_time': datetime.datetime(2020, 9, 17, 10, 16, 43, 258108),
'httperror/response_ignored_count': 10,
'httperror/response_ignored_status_count/403': 9,
'httperror/response_ignored_status_count/404': 1,
'item_scraped_count': 20769,
'log_count/INFO': 75,
'memusage/max': 2707484672,
'memusage/startup': 100196352,
'request_depth_max': 2,
'response_received_count': 42009,
'retry/count': 22,
'retry/reason_count/504 Gateway Time-out': 22,
'scheduler/dequeued': 42031,
'scheduler/dequeued/memory': 42031,
'scheduler/enqueued': 42031,
'scheduler/enqueued/memory': 42031,
'start_time': datetime.datetime(2020, 9, 17, 9, 21, 18, 86960)}
2020-09-17 11:16:43 [scrapy.core.engine] INFO: Spider closed (finished)
downloader/request_bytes 2945159
downloader/request_count 16518
downloader/request_method_count/GET 16518
downloader/response_bytes 3366280619
downloader/response_count 16516
downloader/response_status_count/200 16513
downloader/response_status_count/404 3
dupefilter/filtered 7
elapsed_time_seconds 4805.867308
finish_reason memusage_exceeded
finish_time 1600567332341
httperror/response_ignored_count 3
httperror/response_ignored_status_count/404 3
item_scraped_count 8156
log_count/ERROR 1
log_count/INFO 94
memusage/limit_reached 1
memusage/max 1074937856
memusage/startup 109555712
request_depth_max 2
response_received_count 16516
retry/count 2
retry/reason_count/504 Gateway Time-out 2
scheduler/dequeued 16518
scheduler/dequeued/disk 16518
scheduler/enqueued 17280
scheduler/enqueued/disk 17280
start_time 1600562526474
最佳答案
1.Scheruler 队列/事件请求
与 self.numpages = 418
.
此代码行将创建 418 个请求对象(包括 -to ask OS 委派内存以容纳 418 个对象)并将它们放入调度程序队列:
for page in tqdm(range(1, self.num_pages+1)):
url = 'www.example.com/page={page}'
yield scrapy.Request(url = url, headers=headers, callback = self.prod_url)
每个“页面”请求生成 48 个新请求。
priority
参数可以添加到
scrapy.Request
.
def start_requests(self):
yield scrapy.Request(url = 'www.example.com/page=1', headers=headers, callback = self.prod_url)
def prod_url(self, response):
#get number of page
next_page_number = int(response.url.split("/page=")[-1] + 1
#...
for url in urls_item['urls']:
yield scrapy.Request(url = url, headers=headers, callback = self.parse, priority = 1)
if next_page_number < self.num_pages:
yield scrapy.Request(url = f"www.example.com/page={str(next_page_number)}"
def parse(self, response) # Parse the main product page
#....
try:
new_url = 'www.exampleAPI.com/' + item['active_col_num']
except TypeError:
new_url = 'www.exampleAPI.com/{dummy_number}'
yield scrapy.Request(new_url, callback=self.parse_attr, meta={'item': item}, priority = 2)
使用此蜘蛛配置 - 蜘蛛仅在处理完前一页的产品后才会处理下一页的产品页面,并且您的应用程序不会收到长队列的请求/响应。
DownloaderStats
填充中间件
downloader/response_bytes
stats 参数不会计算未压缩响应的大小,因为它是
process_response
之前调用的方法
process_response
HttpCompressionMiddleware
的方法中间件。
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.stats.DownloaderStats':50
}
在这种情况下:
downloader/request_bytes
stats 参数 - 将减少,因为它不会计算中间件填充的某些 header 的大小。
downloader/response_bytes
stats 参数 - 如果网站使用压缩,将大大增加。
关于python - Scrapy 隐藏的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63936759/
IntentReceiver 正在泄漏 由于 onDetachedFromWindow 在某些情况下未被调用。 @Override protected void onDetachedFromWind
好吧,我很难追踪这个内存泄漏。运行此脚本时,我没有看到任何内存泄漏,但我的 objectalloc 正在攀升。 Instruments 指向 CGBitmapContextCreateImage >
我编写了一个测试代码来检查如何使用 Instrument(Leaks)。我创建了一个单一 View 应用程序,单击按钮后我加载了一个像这样的新 View ... - (IBAction)btn_clk
我正在使用这个简单的代码并观察单调增加的内存使用量。我正在使用这个小模块将内容转储到磁盘。我观察到它发生在 unicode 字符串上而不是整数上,我做错了什么吗? 当我这样做时: >>> from u
我有以下泄漏的代码。 Instruments 表示,泄漏的是 rssParser 对象。我“刷新”了 XML 提要,它运行了该 block 并且发生了泄漏...... 文件.h @interface
我在我编写的以下代码片段中发现了内存泄漏 NSFileManager *fileManager=[[NSFileManager alloc] init]; fileList=[[fileManager
因此,我正在开发HTML5 / javascript rts游戏。观察一直有几种声音在播放。因此,对我来说,是一段时间后声音听起来像是“崩溃”,并且此浏览器选项卡上的所有声音都停止了工作。我只能通过重
下面是我正在使用的一段代码及其输出。 my $handle; my $enterCount = Devel::Leak::NoteSV($handle); print "$date entry $en
在这篇关于 go-routines 泄漏的帖子之后,https://www.ardanlabs.com/blog/2018/11/goroutine-leaks-the-forgotten-sende
我想知道为什么在执行 ./a.out 后随机得到以下结果。有什么想法我做错了吗?谢谢 http://img710.imageshack.us/img710/8708/trasht.png 最佳答案 正
我正在 Swift 中开发一个应用程序,在呈现捕获我放在一起的二维码的自定义 ViewController 后,我注意到出现了巨大的内存跳跃。 该代码本质上基于以下示例:http://www.appc
下面是我的 javascript 代码片段。它没有按预期运行,请帮我解决这个问题。 function getCurrentLocation() { console.log("insi
我们在生产环境中部署了 3 个代理 Kafka 0.10.1.0。有些应用程序嵌入了 Kafka Producer,它们将应用程序日志发送到某个主题。该主题有 10 个分区,复制因子为 3。 我们观察
我正在使用仪器来检测一些泄漏,但有一些泄漏我无法解决; NSMutableString *textedetails = [[NSMutableString alloc] init];
如果我使用性能工具测试我的代码 - 泄漏,它没有检测到任何泄漏。这是否意味着代码没有泄漏任何内存? 我有一个越狱的 iPhone,我可以监控可用内存。如果有人知道,那就是 SBSettings。我测试
我在从 AddressBook 中获取图像时遇到了很大的问题,下面我粘贴了我的代码。此 imageData 从未被释放,在我的 Allocations Instruments 上它看起来总是在内存中它
- (NSMutableArray *)getArrayValue:(NSArray *)array{ NSMutableArray *valueArray = [NSMutableArra
Instruments 工具说这是一个泄漏,有什么想法吗? 我在 for 循环结束时释放变量对象 在上述方法的开头,这就是我设置变量对象的方式,即自动释放; NSMutableArray *varia
我正在跟踪我的 iOS 应用程序的内存泄漏,我有一个奇怪的泄漏导致我的应用程序崩溃......负责的框架是:CGImageMergeXMPPropsWhithLegacyProps。在某些时候,我的应
我正在尝试使用 NSOperationQueue 在后台线程中执行一个方法,如下所示: NSOperationQueue *queue = [NSOperationQueue new]; NS
我是一名优秀的程序员,十分优秀!