Scrapy - 限制已爬网的URL

时间:2015-08-18 16:42:58

标签: regex scrapy

我正在抓取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

1 个答案:

答案 0 :(得分:3)

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

使用正确的正则表达式查找下面的示例。我特意使用了a-z和A-Z中的字符,而不是依赖于“word”符号。

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