如何拒绝某些与Scrapy应该解析的链接相似的链接?

时间:2019-02-11 22:29:43

标签: python-3.x scrapy web-crawler

我正在尝试使用一些我要拒绝的链接和要解析的产品页面来抓取电子商务商店。数据示例:

Parse:
domain.de/nike-Flasche-750-ml
domain.de/Nike-Tasche-schwarz-5
domain.de/Erima-Flasche-weiss-gruen-gelb-5
domain.de/Erima-Hose-rot-blau-gelb-weiss
domain.de/converse-4-Laufschuhe

Deny:
domain.de/service
domain.de/zahlung-versand
domain.de/Mein-Konto
domain.de/geschenkideen-fuer-sie

我尝试过手动将所有内容添加到一个拒绝规则,然后为所有产品domain\.de\/([a-zA-Z0-9-]{2,}-)添加通用规则 那只蜘蛛继续遍历所有类别,但从未解析任何一项。

然后我在表达式中进行了尝试:

domain\.de\/(?!zahlung-versand|service|Mein-Konto|geschenkideen-fuer-sie)([a-zA-Z0-9-]{2,}-)

否定前瞻的页面确实没有被刺穿。但是,仍然没有产品被爬网和解析。

如果我删除了拒绝规则,则将对产品以及应该在拒绝列表中的URL进行解析,然后解析器将中断(因为该页面不包含产品数据/产品列表结构)。

尽管在正则表达式中似乎可以正常工作

https://regex101.com/r/OtW6lb/1

编辑:

一个明显的解决方案是使蜘蛛仍在运行,以简单地做一个返回,以防蜘蛛在某个地方遇到错误。 但我想避免首先抓取页面(如果可能的话,通过正则表达式)

编辑2:

我的规则在JSON中看起来像这样

"rules": [
    {
        "deny": ["\\.de\\/.*__"],
        "follow": false
    },
    {
        "allow": ["\\.de\\/([a-zA-Z0-9-]{2,}-)"],
        "follow": true,
        "use_content": true
    },
    {
        "allow": ["\\.de\\/(cat1|cat2|cat3|cat4)(?:_s[0-9]{1,})?$"],
        "follow": true
    }
],

然后,它们在蜘蛛程序__init__()函数中分配:

for rule in self.MY_SETTINGS["rules"]:
allow_r = ()
if "allow" in rule.keys():
    allow_r = [a for a in rule["allow"]]

deny_r = ()
if "deny" in rule.keys():
    deny_r = [d for d in rule["deny"]]

restrict_xpaths_r = ()
if "restrict_xpaths" in rule.keys():
    restrict_xpaths_r = [rx for rx in rule["restrict_xpaths"]]

Sportygenspider.rules.append(Rule(
    LinkExtractor(
        allow=allow_r,
        deny=deny_r,
        restrict_xpaths=restrict_xpaths_r,
    ),
    follow=rule["follow"],
    callback='parse_item' if ("use_content" in rule.keys()) else None
))

使用此规则顺序,永远不会调用use_content。蜘蛛程序会遍历所有类别页面。 如果我删除了__的拒绝规则,则会在每个页面上调用use_content,并且必须对“关于我们”页面和类似页面中的一些未满足条件进行return

1 个答案:

答案 0 :(得分:1)

  • 您已经使用链接提取规则列表初始化了蜘蛛
  • 如果一个或多个规则与某个链接匹配,则仅first matching rule will be used to parse that link。这可以解释为什么除非您删除拒绝规则,否则不会调用您的回调 use_content 。拒绝规则可能与允许规则匹配相同的链接。因此,链接仅由拒绝规则处理,而不由允许规则处理。请记住,对于LinkExtractor对象
    • If you leave allow parameter empty the link extractor will match all links
    • 拒绝参数可用于将不匹配的链接列入黑名单
    • 对于您来说,拒绝规则与所有不匹配正则表达式的链接匹配。
    • 允许规则将匹配与正则表达式匹配的所有链接,然后在这些链接上调用 use_content 。但是它不会处理已被 deny 规则
    • 匹配的链接

在我看来,您需要将允许拒绝合并为一条规则。 例如,将规则更改为此可能会与您现有的代码配合使用

"rules": [
{
    "deny": ["\\.de\\/.*__"],
    "allow": ["\\.de\\/([a-zA-Z0-9-]{2,}-)"],
    "use_content": true
    "follow": false
},
{
    "deny": ["\\.de\\/.*__"],
    "allow": ["\\.de\\/(cat1|cat2|cat3|cat4)(?:_s[0-9]{1,})?$"],
    "follow": true
}
],