Python 如何使for循环完成,然后才触发scrapy函数
我有一个简单的spider类,有两个函数。一个是从起始页面获取链接并输入它们(同时——获取下一个页面链接),另一个是解析每个链接(它指向的页面)。问题是,我有一个for循环,它在链接上迭代,并为每个链接生成一个Python 如何使for循环完成,然后才触发scrapy函数,python,function,for-loop,scrapy,Python,Function,For Loop,Scrapy,我有一个简单的spider类,有两个函数。一个是从起始页面获取链接并输入它们(同时——获取下一个页面链接),另一个是解析每个链接(它指向的页面)。问题是,我有一个for循环,它在链接上迭代,并为每个链接生成一个scrapy.Request,在这个for循环之后,我有一个if语句要检查,如果当前页面是最后一个,如果不是--我想生成第一个带有下一个页面链接的函数,如果是--停止爬行器并说“last page,”,伙计 def parse(self, response): links = r
scrapy.Request
,在这个for循环之后,我有一个if
语句要检查,如果当前页面是最后一个,如果不是--我想生成第一个带有下一个页面链接的函数,如果是--停止爬行器并说“last page,”,伙计
def parse(self, response):
links = response.xpath('//tags_to_be_chosen/@href').getall()
next_page = response.xpath('//tag_to_be_chosen/@href').get()
check = response.xpath('//tag_to_be_chosen/text()').get()
for link in links:
yield scrapy.Request(response.urljoin(link.strip()), callback=self.parse_page)
if 'specific_string_is' in check: # go to next page, but only after for loop has finished its job
yield scrapy.Request(response.urljoin(next_page.strip()), callback=self.parse)
else: # stop the crawler, because we've reached the last page
print('We\'ve reached the last page!')
def parse_page(self, response):
with open('file_to_write', 'a') as file: # when there's a table of items to be crawled (different tags used than for a single item)
for item in response.xpath('//tags_to_be_chosen/text()').getall():
file.write('{}\n'.format(item.strip()))
else: # when there's a single item to be crawled (different tag used than for multiple items
item = response.xpath('//tag_to_be_chosen').get()
item = item.strip()
item = re.sub('sth_to_be_deleted', '', item)
file.write('{}\n'.format(item))
预期的结果是等待for循环完成调用第2个函数(输入并解析所有链接),然后才输入下一个页面链接。出于某种原因,如果检查,而的仍在链接上循环,则会调用解析下一页的函数(这意味着更改链接),并开始处理新链接,而不是完成“旧”链接
正如评论中指出的那样,一个大的编辑已经完成:你到底为什么要使用收益率?此方法是否已在外部迭代?最后一个IF将在外部迭代完成后调用,但看起来您正在迭代局部变量links
。在那里你可能不需要收益
还不清楚您是通过输入链接然后刮取链接来尝试深度优先,还是广度优先,从页面中获取每个链接,然后解析主页,然后移动到收集的链接
对于链接刮取,可以通过串行或并行两种方式实现
- 对于serial,您只需执行一个For循环,使用其回调调用请求
- 对于并行,您必须有一个线程池,将每个链接处理发送到一个线程,在For循环之后,加入该池以等待所有线程,然后调用函数2
我使用的是yield
,因为我认为这是Scrapy的工作方式。第一个链接位于start\u URL
中<代码>解析
函数解析第一个链接,并从其内容中刮取下一页
链接和所有要输入和刮取页面内容的链接(它是链接的链接
)。然后有一个检查,如果next_page
链接被刮掉了:如果是--它应该在循环完成后用新链接重新调用parse
函数(或者parse
函数只用于start_url
?)。如果没有,则结束该过程。出于某种原因,如果在后面不调用此,则此,但与之并行。这是因为收益率
?是的,收益率会将您的方法转化为生成器,因此当调用您的函数的外部函数调用next
时,for循环将前进。迭代完成后,将继续使用中的代码,如果不是条件
。您应该提供完整的示例,这样更容易理解。整个函数1和2以及这些函数的调用者。我在我的问题中添加了一个大的编辑。现在可能更清楚了,很抱歉给您带来不便。循环时将调用parse_页面,因为您将其定义为请求对象的回调。所以:有人迭代parse
,每次迭代都会创建一个请求,该请求将调用parse\u页面。迭代完成后,将调用parse的最后几行,它们将创建另一个带有回调的请求对象来解析页面。因为parse_页面是同时调用的,所以您必须确保在我看来是线程安全的,parse
将从start_url=[]
中的一个或多个链接开始。在我的情况下,这是一个单一的链接。前3个response.xpath
赋值指的是该链接。然后我循环调用parse\u页面
。但在循环之后,我不会调用parse\u页面
。我正在调用parse
,假设满足条件。无论如何,如何使parse_page
线程安全?您会说“出于某种原因(可能是这样),如果正在检查,而For仍在链接上循环”。我认为这是不可能的,除非多次调用parse
,在这种情况下,其中一个调用可能在循环中,而另一个调用已经到达if
语句。