如何在scrapy中使用限制文本?
How to use restrict text in scrapy?
我的目标是仅从网站的一部分(一个 HTML 节点)中提取 links。
来自域 'quotes.toscrape.com' 我想提取其中包含 'page' 的 link。例如:http://quotes.toscrape.com/page/3/
我试图通过将正则表达式中的 'page' 传递给以下规则来实现此目的:allow、allow_domain 和 restrict_text。我使用了这些正则表达式组合(r'page'、r'/page/'、r'[^]page[^]'、r'.*page.*')除其他外。根据 https://regex101.com/,最后两个效果很好。 None 其中似乎适用于我的代码。
下面是最新的执行情况
class MySpider(CrawlSpider):
name = 'quotes.toscrape.com'
allowed_domains = ['quotes.toscrape.com']
start_urls = ['http://quotes.toscrape.com/']
rules = (
Rule(LinkExtractor(restrict_text=r'.*page.*'), callback='parse'),
)
def parse(self, response):
for span in response.css('span'):
yield {
'span': span.css('span::text').get(),
}
for div in response.css('div'):
yield {
'div': div.css('div::text').get(),
}
next_url_path = response.css(
"a::attr('href')").extract()
for item in next_url_path:
yield scrapy.Request(response.urljoin(item), callback=self.parse)
摘自 Scrapy 文档:https://docs.scrapy.org/en/latest/topics/link-extractors.html
restrict_text(一个正则表达式(或列表))——单个正则表达式(或正则列表表达式)link 的文本必须匹配才能被提取。如果未给出(或为空),它将匹配所有 link。如果给出了正则表达式列表,则 link 将在至少匹配一个时被提取。
我将不胜感激如何正确使用 restrict_text 或任何其他规则来实现相同目标的提示。
您的正则表达式是正确的,但问题出在其他地方。
你的代码有一些小问题。
我把代码改成这样:
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
class MySpider(CrawlSpider):
name = 'quotes.toscrape.com'
allowed_domains = ['quotes.toscrape.com']
start_urls = ['http://quotes.toscrape.com/']
rules = (
Rule(LinkExtractor(allow=r'.*page.*'),
callback='parse_page', follow=True),
)
def parse_page(self, response):
yield {'url': response.url} # It just for test. can be omitted.
for span in response.css('span'):
yield {
'span': span.css('span::text').get(),
}
for div in response.css('div'):
yield {
'div': div.css('div::text').get(),
}
首先在 LinkExtractor
中你必须使用 allow=
而不是 restrict_text=
,因为 allow=
用于 url 而 restrict_text=
用于 link的文本,而不是网址。
其次,由于来自 here 的警告,您无法回调到 parse
方法:
When writing crawl spider rules, avoid using parse as callback, since the CrawlSpider uses the parse method itself to implement its logic. So if you override the parse method, the crawl spider will no longer work.
所以我将 parse
更改为 parse_page
并回调它。
第三,您不必在 parse
方法中提取 links 并从那里发送请求。 CrawlSpider
自动执行此操作。从 parse 方法手动发送的请求不遵循您定义的 rules
。
最后我建议使用这个正则表达式。更简单更常见:
rules = (
Rule(LinkExtractor(allow='page'),
callback='parse_page', follow=True),
)
祝你好运!
我的目标是仅从网站的一部分(一个 HTML 节点)中提取 links。
来自域 'quotes.toscrape.com' 我想提取其中包含 'page' 的 link。例如:http://quotes.toscrape.com/page/3/
我试图通过将正则表达式中的 'page' 传递给以下规则来实现此目的:allow、allow_domain 和 restrict_text。我使用了这些正则表达式组合(r'page'、r'/page/'、r'[^]page[^]'、r'.*page.*')除其他外。根据 https://regex101.com/,最后两个效果很好。 None 其中似乎适用于我的代码。
下面是最新的执行情况
class MySpider(CrawlSpider):
name = 'quotes.toscrape.com'
allowed_domains = ['quotes.toscrape.com']
start_urls = ['http://quotes.toscrape.com/']
rules = (
Rule(LinkExtractor(restrict_text=r'.*page.*'), callback='parse'),
)
def parse(self, response):
for span in response.css('span'):
yield {
'span': span.css('span::text').get(),
}
for div in response.css('div'):
yield {
'div': div.css('div::text').get(),
}
next_url_path = response.css(
"a::attr('href')").extract()
for item in next_url_path:
yield scrapy.Request(response.urljoin(item), callback=self.parse)
摘自 Scrapy 文档:https://docs.scrapy.org/en/latest/topics/link-extractors.html
restrict_text(一个正则表达式(或列表))——单个正则表达式(或正则列表表达式)link 的文本必须匹配才能被提取。如果未给出(或为空),它将匹配所有 link。如果给出了正则表达式列表,则 link 将在至少匹配一个时被提取。
我将不胜感激如何正确使用 restrict_text 或任何其他规则来实现相同目标的提示。
您的正则表达式是正确的,但问题出在其他地方。 你的代码有一些小问题。
我把代码改成这样:
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
class MySpider(CrawlSpider):
name = 'quotes.toscrape.com'
allowed_domains = ['quotes.toscrape.com']
start_urls = ['http://quotes.toscrape.com/']
rules = (
Rule(LinkExtractor(allow=r'.*page.*'),
callback='parse_page', follow=True),
)
def parse_page(self, response):
yield {'url': response.url} # It just for test. can be omitted.
for span in response.css('span'):
yield {
'span': span.css('span::text').get(),
}
for div in response.css('div'):
yield {
'div': div.css('div::text').get(),
}
首先在 LinkExtractor
中你必须使用 allow=
而不是 restrict_text=
,因为 allow=
用于 url 而 restrict_text=
用于 link的文本,而不是网址。
其次,由于来自 here 的警告,您无法回调到 parse
方法:
When writing crawl spider rules, avoid using parse as callback, since the CrawlSpider uses the parse method itself to implement its logic. So if you override the parse method, the crawl spider will no longer work.
所以我将 parse
更改为 parse_page
并回调它。
第三,您不必在 parse
方法中提取 links 并从那里发送请求。 CrawlSpider
自动执行此操作。从 parse 方法手动发送的请求不遵循您定义的 rules
。
最后我建议使用这个正则表达式。更简单更常见:
rules = (
Rule(LinkExtractor(allow='page'),
callback='parse_page', follow=True),
)
祝你好运!