首页 > 解决方案 > Powershell - 如何在侧面独家选择文本

问题描述

我正在使用 Powershell 进行一些网络抓取。网站上有一个项目,代码如下:

<h1 class="">1001 Nights&nbsp;<span id="titleYear">(<a href="/year/1968/?ref_=tt_ov_inf">1968</a>)</span>            </h1>

我想提取里面的文字,这个文字:

1001 Nights

但不是这个文本:

<span id="titleYear">(<a href="/year/1968/?ref_=tt_ov_inf">1968</a>)</span>

网站上的 CSS 选择器类似于:

 "#title-overview-widget > div.vital > div.title_block > div > div.titleBar > div.title_wrapper > h1"

在 Stack Overflow 上进行一些搜索,我找到了该工作的代码,如下所示。

$Result =  Invoke-WebRequest -Uri "https://www.imdb.com/title/tt0062940/?ref_=ttls_li_tt"
$movieTitleSelector = "#title-overview-widget > div.vital > div.title_block > div > div.titleBar > div.title_wrapper > h1"
$NodeList = $Result.ParsedHtml.querySelectorAll( $movieTitleSelector)
$PsNodeList = @()
for ($i = 0; $i -lt $NodeList.Length; $i++) { 
   $PsNodeList += $NodeList.item($i)
}
$PsNodeList | ForEach-Object {
   $_.InnerText
}

结果是:

1001 Nights (1968)

“1001 夜”是电影名称,“1968”是包含在<span></span>. 我只想要标题部分而不是发布年份部分。我在 Stack Overflow 上找到了一些代码,它说我可以通过将上面文本中的<h1>代码<span>更改为:

$movieTitleSelector = "#title-overview-widget > div.vital > div.title_block > div > div.titleBar > div.title_wrapper > h1 :not(span)"

但是当我运行代码时,它会抛出

Invalid argument.
At line:1 char:1
+ $NodeList = $Result.ParsedHtml.querySelectorAll( "#title-overview-wi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException

错误。我认为发生错误是因为 $movieTitleSelector 字符串中有一个冒号,但我不太确定。任何人都请告诉我如何在<h1>元素中获取标题文本,而不是在<span>标签内。谢谢你。

标签: csspowershell

解决方案


为什么不呢,只需在提取物中使用正则表达式删除年份或任何您想要的字符串。

$movieTitleSelector = "#title-overview-widget > div.vital > div.title_block > div > div.titleBar > div.title_wrapper > h1 :not(span)" -replace '\s\(\d{4}\)'

'1001 Nights (1968)' -replace '\s\(\d{4}\)'
<#
# Results

1001 Nights
#>

更新

试试这个...根据你的反应。

$Result =  Invoke-WebRequest -Uri "https://www.imdb.com/title/tt0062940/?ref_=ttls_li_tt"
$movieTitleSelector = "#title-overview-widget > div.vital > div.title_block > div > div.titleBar > div.title_wrapper > h1"
$NodeList = $Result.ParsedHtml.querySelectorAll( $movieTitleSelector)

$PsNodeList = @()

for ($i = 0; $i -lt $NodeList.Length; $i++) { 
   $PsNodeList += $NodeList.item($i)
}
$PsNodeList | 
ForEach-Object {
   $_.InnerText -replace '\s\(\d{4}\)' 
}

推荐阅读