Python 3.x 如何拒绝与Scrapy应该解析的链接相似的链接?
我正试图抓取一个电子商务商店,其中包含一些我想要拒绝的链接和我想要解析的产品页面。数据示例如下:Python 3.x 如何拒绝与Scrapy应该解析的链接相似的链接?,python-3.x,scrapy,web-crawler,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
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,}-
那个蜘蛛一直在浏览所有类别,但从未解析过一个项目
然后我在expression中尝试过:
domain\.de\/(?!zahlung-versand|service|Mein-Konto|geschenkideen-fuer-sie)([a-zA-Z0-9-]{2,}-)
负面展望的页面确实没有被扣掉。但仍然没有对产品进行爬网和解析
如果我删除了拒绝规则,那么将解析产品以及应该位于拒绝列表上的URL,然后解析器将中断(因为页面不包含产品数据/产品列表结构)
不过,在regex中,事情似乎起了作用:
编辑:
一个显而易见的解决方案是让爬行器仍然运行,只要在爬行器在某处遇到错误时返回即可。
但我首先希望避免爬行页面(如果可能,通过regex)
编辑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
}
],
然后,在spider\uuuu init\uuuu()函数中分配它们:
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\u content
永远不会被调用。蜘蛛会浏览所有的分类页面。
如果我删除了\uuuuu
的拒绝规则,则在每个页面上都会调用使用内容
,我必须从“关于我们”页面和类似页面中返回一些未满足的条件。
- 您已使用链接提取规则列表初始化了spider
- 如果一个或多个规则与链接相匹配,则只有。这可以解释为什么除非删除拒绝规则,否则不会调用回调use\u content。可能拒绝规则与允许规则匹配的链接相同。因此,链接仅由拒绝规则处理,而不是由允许规则处理。请记住,对于LinkExtractor对象
- deny参数可用于将不应匹配的链接列入黑名单
- 在您的情况下,deny规则将匹配与正则表达式不匹配的所有链接
- allow规则匹配所有与正则表达式匹配的链接,然后对这些链接调用use\u content。但它不会处理已经被拒绝规则匹配的链接
我觉得好像你需要把你的允许和拒绝组合成一条规则。
例如,将规则更改为此可能会更好地处理现有代码
"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
}
],
链接在html正文中的位置是否存在差异?如果是这样的话,您可以使用XPath来识别html的各个部分,以便在其中搜索链接。让我知道,如果你愿意,我可以给你写一个示例解决方案……我也通过restrict\u xpaths=()
参数考虑了这个问题。排除页面的页眉和页脚可能有用。但是在这种情况下,我想否认的一些URL嵌套在主导航中,就在应该解析的其他URL旁边。嗯,很难说。拒绝域列表是否已修复?或者每页都不同?对于这个商店,我有一个固定的列表,我正在构建它-但是也有一些动态URL来自过滤器导航(我刚刚发现)。它们可以通过\uuuu
来识别:domain.de/geschenkideen-fuer-sie\uu schuhgroesse
您是否重新编译了正则表达式?它必须是正则表达式对象。不是严格的是的,你是对的-现在我有了允许、拒绝和限制的规则,就像你建议的那样。另外:rules.append(Rule..)在我的代码中也缩进错误-在for之后,所以只分配了最后一条规则,现在产品被删除了。