Python 如何使for循环完成,然后才触发scrapy函数

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

我有一个简单的spider类,有两个函数。一个是从起始页面获取链接并输入它们(同时——获取下一个页面链接),另一个是解析每个链接(它指向的页面)。问题是,我有一个for循环,它在链接上迭代,并为每个链接生成一个
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
语句。