- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我创建了一个刮板,以从网页上获取一些产品名称。运行正常。我已经使用CSS选择器来完成这项工作。但是,我唯一不了解的是选择器a::text
和a ::text
之间的区别(请不要忽略后者中a
和::text
之间的空间)。当我运行脚本时,无论选择哪个选择器,我都会得到完全相同的结果。
import requests
from scrapy import Selector
res = requests.get("https://www.kipling.com/uk-en/sale/type/all-sale/?limit=all#")
sel = Selector(res)
for item in sel.css(".product-list-product-wrapper"):
title = item.css(".product-name a::text").extract_first().strip()
title_ano = item.css(".product-name a ::text").extract_first().strip()
print("Name: {}\nName_ano: {}\n".format(title,title_ano))
title
和
title_ano
都包含相同的选择器,并在后者中留出空格。尽管如此,结果始终是相同的。
最佳答案
有趣的观察!我花了过去的两个小时研究这个问题,结果发现,它所带来的不仅仅是眼神。
如果您来自CSS,则可能希望以与a::text
,a::first-line
,a::first-letter
或a::before
相同的方式编写a::after
。没有惊喜。
另一方面,标准选择器语法建议a ::text
与::text
元素的后代的a
伪元素匹配,使其等效于a *::text
。但是,.product-list-product-wrapper .product-name a
没有任何子元素,因此按权利,a ::text
应该不匹配。它确实匹配的事实表明Scrapy没有遵循语法。
Scrapy使用Parsel(基于cssselect本身)将选择器转换为XPath,即::text
的来源。考虑到这一点,让我们研究一下Parsel如何实现::text
:
>>> from parsel import css2xpath
>>> css2xpath('a::text')
'descendant-or-self::a/text()'
>>> css2xpath('a ::text')
'descendant-or-self::a/descendant-or-self::text()'
因此,就像cssselect一样,跟随后代组合器的所有内容都将转换为
descendant-or-self
轴,但是由于文本节点是DOM中元素节点的适当子代,因此
::text
被视为独立节点,并直接转换为
text()
,后者与
descendant-or-self
一起使用轴,匹配
a
元素后代的任何文本节点,就像
a/text()
匹配
a
元素的任何文本节点子代(子代也是子代)一样。
*
添加到选择器中,也会发生这种情况:
>>> css2xpath('a *::text')
'descendant-or-self::a/descendant-or-self::text()'
但是,
descendant-or-self
轴的使用意味着
a ::text
可以匹配
a
元素中的所有文本节点,包括嵌套在
a
中的其他元素中的所有文本节点。在以下示例中,
a ::text
将匹配两个文本节点:
'Link '
后跟
'text'
:
<a href="https://example.com">Link <span>text</span></a>
因此,尽管Scrapy的
::text
的实现严重违反了Selectors语法,但似乎是非常有意地这样做的。
::attr()
1的行为类似。当没有任何子元素时,以下选择器都与属于
id
元素的
div
属性节点匹配:
>>> css2xpath('div::attr(id)')
'descendant-or-self::div/@id'
>>> css2xpath('div ::attr(id)')
'descendant-or-self::div/descendant-or-self::*/@id'
>>> css2xpath('div *::attr(id)')
'descendant-or-self::div/descendant-or-self::*/@id'
...但是
div ::attr(id)
和
div *::attr(id)
将匹配
id
的后代中的所有
div
属性节点及其自己的
id
属性,例如以下示例:
<div id="parent"><p id="child"></p></div>
当然,这是一个不太合理的用例,因此必须怀疑这是否是
::text
实现的意外副作用。
>>> css2xpath('a [href]')
'descendant-or-self::a/descendant-or-self::*/*[@href]'
这样可以使用附加的隐式
descendant-or-self::*/*
轴将后代组合器正确转换为
child
,从而确保从未在
[@href]
元素上测试
a
谓词。
a::text
元素仅包含文本,或者您仅对该a
元素的顶级文本节点而不是其嵌套元素感兴趣,请使用a
。a ::text
元素包含嵌套元素,并且您要提取此a
元素内的所有文本节点,请使用a
。a ::text
元素仅包含文本,则可以使用a
,但是其语法令人困惑,因此,为了保持一致,请改为使用a::text
。::attr()
出现在(从2021年开始被废弃)
Non-element Selectors spec中,正如您所期望的,它的行为与Selectors语法一致,从而使其在Scrapy中的行为与规范不一致。另一方面,规范中明显缺少
::text
;基于此答案,我认为您可以对原因做出合理的猜测。
关于python - Scrapy选择器 "a::text"和 "a::text"之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48556919/
我目前正在创建一个正则表达式来拆分所有匹配以下格式的字符串:&[text(text - text text) !text]。这里的文本实际上可以是任何字符。并且间距很重要。文本将如图所示列出。 我已经
这个问题在这里已经有了答案: Remove duplicate commas and extra commas at start/end with RegExp in Javascript, and
我有以下代码。 from xml.dom.minidom import Document doc = Document() root = doc.createElement('root') doc.a
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Find text string in jQuery and make it bold 如何使用 jQuer
我使用 libmagic 在我的元素的 Web 界面中获取文件的 MIME 类型。我在 css 和 js 文件上得到文本/纯 mime 类型。 例如 chromium 显示以下警告: Resource
起初我必须阅读很多教程,但我仍然不知道我做错了什么...... 我想内联使用 4 个 div。在我想放置的那些 div 中:文本、图像、文本、文本。我希望中间文本自动设置为最大宽度。 我写了一个简单的
我想替换所有出现的 [b: "text"]至text使用 JavaScript 和 RegEx。目前我知道如何替换 [b: ""]至使用'/\[b: ""\]/g'但我不知道如果 " 之间有文本该怎么
这可能是一个幼稚的问题,但我想知道是否有比使用 text() 更好的方法将文本添加到绘图中。注意,我也在使用 layout()以及。具体来说,我有一个情节的一部分,我想在其中添加一些带有标题的文本,然
我必须反复从 latex 源粘贴代码,因此每次都必须做很多查找和替换操作('“a'=>'ä','” o'=>'ö',...) 。 有没有一种方法可以存储这些搜索和替换规则,例如,我可以通过一次按键执行
当我在Sublime Text 3代码屏幕中编写代码时,它连续地向右滑动,如图所示。我该怎么办? 请注意第10行。 最佳答案 如果您只想为当前 View (正在编辑的当前文件)激活自动换行,只需vie
是否有可能更改 sublime text 中的默认字体目录?我只想使用可移植 sublime 文本存储在我的 pendrive 上的字体,这样我就不必在我使用可移植 sublime 文本的每台机器上安
我是 Android 开发的新手,我有一个愚蠢的问题。如何将“文本字段”框放在一行中的文本旁边。 例子: Please Enter the number: [ ] 关于 "t
我想自动将“我的文本”更改为“我的文本”,因为这是用德语写的正确方式。引号可以在文本中的任何位置。 有没有一种简单的方法可以实现这一点? 解决方案应该检查第一个字符,最后一个字符,比如“this”,或
我想知道是否有特殊的语法来绑定(bind)与现有文本连接的文本。 像这样。 显然,这行不通。 什么是最佳实践? 使用 SL4。 最佳答案 使用StringFormat在 Binding 上。 WPF
我认为它应该打印“真实文本”,因为它相当于 true console.log('true text' || true ? 'text' : 'text1'); 但是,输出是“文本”;抱歉,如果是愚蠢的
有没有办法通过 css 打破文本,以便中间有一个“空白”?目前我正在通过手工打破文本来解决这个问题 -但这是愚蠢的。我知道有一个函数可以让文本在另一个 div 中结束和开始,但 IE 不支持它。 文本
我想为我的Tcl/Tk工具实现一个效果:在text控件中,根据具体情况,希望高亮一些线条的背景色,其他线条正常透明.有可能吗? 我尝试了一些选项,例如:-highlightbackground 、-i
我正在尝试解析原始维基百科文章内容,例如the article on Sweden ,使用re.sub()。但是,我在尝试替换 {{some text}} block 时遇到了问题,因为它们可以包含更
我试图先删除 ComboBox 中的所有内容。然后在其前面添加文本,但保留了一些旧文本。有没有办法重置或清除 ComboBox?或者我怎样才能最好地实现这一目标? public void GetBad
我知道我们应该创建 Example对象并将其传递给 nlp.update() 方法。根据 docs 中的示例, 我们有 for raw_text, entity_offsets in train_da
我是一名优秀的程序员,十分优秀!