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