Python Scrapy,开发可伸缩的spider-按元素属性提取Xpath

Python Scrapy,开发可伸缩的spider-按元素属性提取Xpath,python,xpath,scrapy,scrapy-spider,Python,Xpath,Scrapy,Scrapy Spider,所以我正在做一个网页抓取项目,它从20多个网站的列表中提取大量的产品信息(如价格、位置、名称等)。。。到目前为止,我已经创建了一个通用MasterSpider(类似于这里讨论的:),根据站点的特定体系结构,我从中继承和覆盖它 然而,在基本上重复了很多代码并希望使这个项目具有可伸缩性之后,我开始致力于推广我的MateSpider,这样它就可以扩展到其他网站,理想情况下只需使用最少的参数(如start_url)就可以实例化。换句话说,我现在寻找html标记属性值/文本值,而不是通过Xpath(跨域不

所以我正在做一个网页抓取项目,它从20多个网站的列表中提取大量的产品信息(如价格、位置、名称等)。。。到目前为止,我已经创建了一个通用MasterSpider(类似于这里讨论的:),根据站点的特定体系结构,我从中继承和覆盖它

然而,在基本上重复了很多代码并希望使这个项目具有可伸缩性之后,我开始致力于推广我的MateSpider,这样它就可以扩展到其他网站,理想情况下只需使用最少的参数(如start_url)就可以实例化。换句话说,我现在寻找html标记属性值/文本值,而不是通过Xpath(跨域不一致)定位元素

这适用于一般/一致的目标,如从起始页识别类别链接(通常在链接中包含类别),但对于查找产品名称、价格等方面,它是缺乏的。必须构建一个xpath条件列表(比如@class=a或b或c/contains(,'a')或contains(,'b'))有点达不到目的

我意识到我还可以传递一些xpath条件来实例化spider,这可能是我必须要做的,但我更愿意让它尽可能易于使用和扩展

我的想法是,在解析各个产品页面之前,发出一个虚拟请求,查找我想要的信息,并反向工作以实际识别信息的xpath,然后在后续请求中使用该信息

所以我想知道是否有人对如何提取给定元素的Xpath有什么好的想法,比如说它可能包含的标记值列表,或者其中的文本匹配。。。我意识到一系列的尝试可以起作用,但这又是一种创可贴,而不是一种解决方案。如果我必须使用像selenium或解析器这样的东西来实现这一点,这也是一个选项

对任何想法或新观点都非常开放


谢谢

在工作中,我不得不搜刮成千上万的新闻网站,正如你所料,没有一个适合所有人的解决方案。因此,我们的策略是采用一种“通用”方法,通过启发式尝试提取所需的信息,对于麻烦的网站,我们将为该网站提供一个特定XPath列表

所以我们的总体结构是这样的:

parsers = {
    "domain1": {
        "item1":  "//div...",
        "item2":  "//div...",
    },
    "domain2": {
        "item1":  "//div...",
        "item2":  "//div...",
    },
}

def parse(self, response):
    domain = urlparse(response.url).netloc # urlparse comes from urllib.parse
    try:
        parser = self.parsers[domain]
        return self.parse_with_parser(response, parser)
    except Exception as e:
        return self.parse_generic(response)
解析器命令我实际上保存在一个单独的文件中。您还可以将其保存在数据库或文件中,并在爬行器加载时访问信息,这样您就不必在每次需要更改某些内容时都编辑爬行器

编辑:

回答问题的第二部分,根据您需要做的事情,您可以编写考虑多种条件的XPath。例如:

"//a[contains(@class, 'foo') or contains(@class, 'bar')]"
甚至可能

"//a[contains(@class, 'foo') or contains(@class, 'bar')] | //div[@class='something'] | //td/span"

“|”将允许您“链接”可能包含要提取内容的不同表达式。不同表达式上的and/or运算。

所以当你说“通过启发式将尝试提取所需信息”时,你能更具体一点吗。。。与parse泛型类一样,如何在没有xpath的情况下提取信息?您是在寻找包含特定属性值/文本的html标记,还是更复杂的html标记?这些标记非常特定于域,并且经过了大量测试/反复试验。例如,为了提取文章标题,我会查看几个地方(标题标签,og:title meta,尝试一些XPath,一些标签),并制定一套规则,规定我应该在什么时候相信我有正确的标题我还用一些可能适合您需要的内容编辑了我的答案,并且没有好的启发法那么复杂/难实现。我很欣赏,这就是我一直以来的想法。我想知道启发式方法有多难,似乎我应该把它放在次要位置。