在PowerShell中的数组上使用Invoke-WebRequest

时间:2018-04-25 21:22:37

标签: arrays multithreading powershell runspace

我正在尝试编写一个脚本,它将从here获取财富100个URL,将它们放入一个数组中,然后编写一个使用Invoke-WebRequest获取这些URL的内容的运行空间将该内容写入文件。这是我到目前为止的代码:

#Importing Modules
Import-Module PoshRSJob

#variable declaration
$page = Invoke-WebRequest https://www.zyxware.com/articles/4344/list-of-fortune-500-companies-and-their-websites
$links = $page.Links
$tables = @($page.ParsedHtml.GetElementsByTagName("TABLE"))
$tableRows = $tables[0].Rows

#loops through the table to get only the top 100 urls.
$urlArray = @()

foreach ($tablerow in $tablerows) {
    $urlArray += New-Object PSObject -Property @{'URLName' = $tablerow.InnerHTML.Split('"')[1]}
    #Write-Host ($tablerow.innerHTML).Split('"')[1]
    $i++
    if ($i -eq 101) {break}
}

#Number of Runspaces to use
#$RunspaceThreads = 1

#Declaring Variables 
$ParamList = @($urlArray)
$webRequest = @()

$urlArray | start-rsjob -ScriptBlock {
    #$webRequest = (Invoke-WebRequest $using:ParamList)
    #Invoke-WebRequest $urlArray
    #Invoke-WebRequest {$urlArray}
    #Get-Content $urlArray
} 

我现在遇到的问题是我无法让Invoke-WebRequestGet-Content向我提供数组中实际包含的网址内容。您可以在scriptblock中看到,我注释掉了一些不起作用的行。

我的问题是:使用运行空间,我需要做什么才能使用Get-Content从数组中的所有URL中提取数据,然后将其写入文件?

1 个答案:

答案 0 :(得分:0)

您可以调整当前查询以获取前100个公司名称。这会让前面空荡荡的公司不知所措。请考虑使用[PSCustomObject] @{ URLName = $url }替换旧版New-Object PSObject

$urlArray = @()
$i = 0
foreach ($tablerow in $tablerows) {
    $url = $tablerow.InnerHTML.Split('"')[1]
    if ($url) {
        # Only add an object when the url exists
        $urlArray += [PSCustomObject] @{ URLName = $url }
        $i++
        if ($i -eq 100) {break}
    }
}

要并行运行请求,请使用脚本块Start-RSJob。然后Invoke-Webrequest并行运行。请注意,在此示例中,$_引用了当前由管道传输的数组元素,该元素由具有URLName属性的对象组成,但您需要小心一点,因为它们在scriptblock中使用了哪些变量可能不会像你期望的那样被重新取消。

# Run the webrequests in parallel
# $_ refers to a PSCustomObject with the @{ URLName = $url } property
$requests = ($urlArray | start-rsjob -ScriptBlock { Invoke-WebRequest -Uri $_.URLName })

然后,您可以等待所有作业完成并对结果进行一些后期处理。 这里只写了网站内容的长度,因为页面本身很长。

# Get the results
# $_.Content.Length gets the length of the content to not spam the output with garbage
$result = Get-RSjob | Receive-RSJob | ForEach { $_.Content.Length }
Write-Host $result