【问题标题】:Scrapy - Limiting the URLs crawledScrapy - 限制抓取的 URL
【发布时间】:2015-11-11 17:22:14
【问题描述】:

我正在抓取 Erowid 并尝试从该站点收集数据。我编码的蜘蛛

import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.selector import HtmlXPathSelector



class ExperiencesSpider(CrawlSpider):
    name = "experiences"
    allowed_domains = ["www.erowid.org"]
    start_urls = ['https://www.erowid.org/experiences/exp_list.shtml']
    rules = [ 
        Rule(LinkExtractor(allow =('subs/exp_\w+.shtml')), follow = True)    
    ]
    def parse_item(self, response):
        pass

问题是蜘蛛不仅会爬到我想要的网站,例如 https://www.erowid.org/experiences/subs/exp_aPVP.shtml (它提供了我需要的所有描述) 但也会爬入该站点的子部分,例如https://www.erowid.org/experiences/subs/exp_aPVP_General.shtml,这是我需要的代码的一个子部分。

我正在尝试编辑我的代码,以便它拒绝任何带有下划线的内容,我认为 \w+ 会这样做但没有。我尝试使用 [a-z]+ ,但蜘蛛都停止了。

为了获得所有所需的网站,正确的正则表达式是什么,那些在 www.erowid.org/experiences/sub/exp_(drugname 形式的药物名称后没有下划线的网站).shtml

【问题讨论】:

    标签: regex scrapy


    【解决方案1】:

    regex101 上测试您的正则表达式后,您的正则表达式似乎正在识别两个网址,而不仅仅是第一个。 这让我认为你的正则表达式有问题(如你所说),而不是scrapy正则表达式引擎本身的问题(应该是python的re

    在下面找到您使用正确正则表达式的示例。我专门使用了 a-z 和 A-Z 中的字符,而不是依赖“单词”符号。

    class ExperiencesSpider(CrawlSpider):
    name = "experiences"
    allowed_domains = ["www.erowid.org"]
    start_urls = ['https://www.erowid.org/experiences/exp_list.shtml']
    rules = [ 
        Rule(LinkExtractor(allow =('subs/exp_[a-zA-Z]+.shtml')), follow = True)
    ]
    def parse_item(self, response):
        pass
    

    正如Regex101 所示,“Word”符号已知为:\w+ match any word character [a-zA-Z0-9_](下划线就在此处,作为被视为word 符号一部分的标记之一)

    另一种可行的方法是使用deny() attribute,再加上您现有的allow(),并使deny() 正则表达式知道如何排除不需要的网址:

    class ExperiencesSpider(CrawlSpider):
        name = "experiences"
        allowed_domains = ["www.erowid.org"]
        start_urls = ['https://www.erowid.org/experiences/exp_list.shtml']
        rules = [ 
            Rule(LinkExtractor(allow =('subs/exp_\w+.shtml')), follow = True),    
            Rule(LinkExtractor(deny=('subs/exp_[a-zA-Z]+_\w+.shtml')), follow = False)
        ]
        def parse_item(self, response):
            pass
    

    【讨论】:

    • 仅供参考:我还对 regex101 进行了一些测试,并以以下正则表达式结束: 'subs/exp_[^_]+\.shtml' 。这会产生没有第二个下划线出现的每个 url,而不是肯定列表。
    • 这也是一种方法。我试图弄清楚如何指定“exp 后跟一个下划线,后跟任何单词,而不是我的任何其他下划线”。我猜TIL
    猜你喜欢
    • 1970-01-01
    • 2022-12-07
    • 1970-01-01
    • 2017-04-06
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多