Python 使用Scrapy迭代地从两个站点获取项目

Python 使用Scrapy迭代地从两个站点获取项目,python,scrapy,Python,Scrapy,我正在用Scrapy编写一个scraper,我担心它的异步行为可能会导致问题 我从一个有多个链接的页面开始,每个链接都有一个x。这些x已保存(下载)。然后我转到另一个页面b,在那里我使用从a链接之一获得的一些信息(所有链接都是常量)来选择和下载y 然后我“配对”x和y,如何配对并不重要,重要的是x和y都存在(下载)。 现在我会考虑我的起始页( StisturyURLS < /代码>),我会得到“转到”页面的链接(如我在第1页,现在我要到第2页),然后我要求从一开始就开始这个过程。 代码大致如下所

我正在用Scrapy编写一个scraper,我担心它的异步行为可能会导致问题

我从一个有多个链接的页面开始,每个链接都有一个
x
。这些
x
已保存(下载)。然后我转到另一个页面
b
,在那里我使用从
a
链接之一获得的一些信息(所有链接都是常量)来选择和下载
y

然后我“配对”
x
y
,如何配对并不重要,重要的是
x
y
都存在(下载)。
现在我会考虑我的起始页(<代码> StisturyURLS < /代码>),我会得到“转到”页面的链接(如我在第1页,现在我要到第2页),然后我要求从一开始就开始这个过程。 代码大致如下所示:

# ..imports, class etc.

start_url = ['bla']
start_url_buddy = ['bli']


def parse(self, response):

    urls = response.xpath(...)
    for url in urls:
        yield scrapy.Request(url, callback=self.parse_child)

    yield scrapy.Request(start_url_buddy, callback=self.parse_buddy)

    pair_function(self.info)

    # Finished processing start page. Now turning the page.
    # could do smth like this to get next page:
    nextpage_url = response.xpath(...@href)
    yield scrapy.Request(nextpage_url)

    # or maybe something like this?
    start_urls.append(response.xpath(...@href))

# links `a`
def parse_child(self, response):

    # info for processing link `b`
    self.info = response.xpath(...)

    # Download link
    x = response.xpath(...)
    # urlopen etc. write x to file in central dir

# link `b`
def parse_buddy(self, response):

    # Download link
    y = response.xpath(...self.info...)
    # urlopen etc. write y to file in central dir
我还没有谈到翻页部分,我担心这是否会像预期的那样起作用(我正在摆弄合并功能atm,获得
x
s和
y
对于一页来说效果很好)。我不在乎
x
s和
y
的获取顺序,只要它在
pair\u函数
和“翻页”(当解析函数应该再次启动时)之前

我看了其他几个问题,比如,但是我没有从他们那里得到一个明确的答案。我的基本问题是我不确定异步是如何实现的(文档中似乎没有解释)


EDIT:我担心的是,
产生的请求(nextpage\u url)
将在前一个请求完成之前被调用。我现在在想,我可以通过在所有事情都完成后添加
start\u URL
(正如我在代码中所做的那样)来防范这种情况(这样的逻辑应该会导致对附加url调用
parse
函数?

您将无法知道请求何时完成,因为scrapy正在处理您的所有请求,但它不会等待请求的服务器在处理下一个挂起的请求之前返回响应

关于异步调用,您不知道它们将在“何时”结束,但您知道“何处”,这是的回调方法。因此,例如,如果您确实希望在一个请求之后执行另一个请求,您可以执行以下操作:

def callback_method_1(self, response):
    # working with response 1
    yield Request(url2, callback=self.callback_method_2)

def callback_method_2(self, response):
    # working with response 2, after response 1
    yield Request(url3, callback=self.callback_method_3)

def callback_method_3(self, response):
    # working with response 3, after response 2 
    yield myfinalitem
在本例中,您肯定知道第一个请求是在
url2
请求之前完成的,而那是在
url3
之前完成的。正如您所看到的,您不知道这些请求是“何时”完成的,但您知道“在哪里”


还请记住,回调之间通信的一种方式是使用request参数。

当我在按顺序请求页面之前执行此操作,但它们的响应是异步接收的。这就是您要问的吗?编辑OP可以更清楚地了解我害怕什么。我不在乎第一次
请求的顺序。
调用(url
url
)中的url
url
)。对我来说唯一重要的是,在最后一个调用
之前,这些都完成了。请求(nextpage\u url)
。我只向您解释了scrapy是如何工作的。如果您从一个方法发送多个请求(如
解析
)方法,所有这些请求都是异步处理的,所以它在哪一行代码中并不重要,您必须使您的代码适应这种回调的想法。啊,对不起,谢谢。我可以“隐藏”吗将请求放在单独的函数中?如果我有一个
parse
函数和三个
yield
请求,并且我将最后一个放在单独的函数中,这会保证前两个在最后一个之前得到处理吗?您可以将两个请求的
回调
方法设置为相同的方法,并且在内部该方法可能会检查是否是“第二次”调用它(使用元参数,甚至是类反参数),然后调用所需的方法