Replies: 6 comments 3 replies
|
It doesn't trigger when the spider has emitted no items at all, it triggers when the spider has emitted no items in the last N seconds, so getting "scraped Z items" messages from time to time isn't enough. |
|
Perhaps I wasn't as clear as I could be in my initial post. To be more concrete, I set CLOSESPIDER_TIMEOUT_NO_ITEM to 3600 seconds. My spider ran for slightly more than one hour before it timed out with the CLOSESPIDER_TIMEOUT_NO_ITEM reason. During the spider run, I also added a logging statement right before the item is yield, i.e. right before: This logging statement happens multiple times during the job run - in my case 3000 times in an hour, spread over the entire hour. And definitely within a minute before the spider is stopped by CLOSESPIDER_TIMEOUT_NO_ITEM! So it's not just scraping, it's also processing/emitting the item (unless Scrapy doesn't consider this emitting an item). |
|
Scrapy doesn't consider this emitting an item for purposes of CLOSESPIDER_TIMEOUT_NO_ITEM, what counts is the |
|
I added some logging to closespider.py to debug this issue, specifically in _count_items_produced method. What's interesting in my case (for my spider) was that I was noticing _count_items_produced was getting invoked twice in quick succession. I logged out the self.items_in_period values in these two logging statements and noticed the first resulted in a nonzero value greater than 0 - but then the second logging statement which happened shortly thereafter (less than a second later) was then set to 0! My spider has some fairly intensive operations using the Playwright browser which I presume could be competing with the Scrapy main event loop for resources. Could this lead to event loop starvation and what I described earlier with the logging? Perhaps this leads to checks to _count_items_produced to accumulate over a time period as these invocations/checks get delayed and "pile up", leading more to a possible race condition with the check? To fix this, I modified some of the closespider.py code to note when the last item was scraped instead of counting how many items were scraped, then adding a check to see when this item was last scraped compared to the CLOSESPIDER_TIMEOUT_NO_ITEM value in the _count_items_produced method. Checking the last scraped time seems to be a more reliable way of handling this and this technique seems to work in my case. I tried to keep the code structure and organization as similar to the original closespider.py as possible. I'll probably need to test this some more though!: |
Do you mean you are using it synchronously? |
|
#7377 switched from I also had an LLM make some tests related to this and it has found a bug which only triggers with uvloop on my machine, do you remember if you were using uvloop in any of the setups you listed? In any case, I think there are still things to improve in |
Uh oh!
There was an error while loading. Please reload this page.
Just curious if anyone else has come across this issue? The Scrapy logs clearly show items are being scraped and processed. The Crawled X pages (at Y pages/min), scraped Z items (at A items/min) message varies each minute, but the spider stops with the reason closespider_timeout_no_item after the closespider_timeout_no_item period is exceeded. What makes it doubly interesting is I encounter this issue when running the spider on Scrapy 2.14 on a Docker container (using the python:3.11.13-bullseye image, linux/amd64) on a Ubuntu 25.10 host. However, when running the same spider on Scrapy 2.14 on a Docker container (using the python:3.11.13-bullseye image, linux/amd64) on a MacOS Tahoe 26.3 host, the spider runs without encountering the closespider_timeout_no_item timeout, even when it runs longer than the closespider_timeout_no_item period.
If I have some time, I'll see if I can replicate this on a simple project I can share.
All reactions