Powershell 简易爬虫,提取种子网站的磁力链接


一. 需求

⏹有网站如下所示,先要求从按照关键词搜索到的网页中,提取出所有的磁力链接。

在这里插入图片描述


二. 分析

2.1 思路分析

  • 打开网页之后,从网页中先提取出所有的标题相关的url
  • 然后再打开所有提取到的url
  • 再从每一个新打开的页面中获取磁力链接所在a标签的href属性值

2.2 技术点

  • Invoke-WebRequest:发送网络请求
  • workflow
    • workflow 是一种特殊的语法结构,用于创建并发执行的工作流。工作流允许你定义一系列步骤,这些步骤可以同时执行或并行执行,适用于需要处理大量数据或需要在多个计算资源上执行任务的情况。
    • 在 foreach -parallel 循环内并行执行多个任务,从而加快处理速度。
    • InlineScript { ... }:内联脚本块用于在工作流中执行本地 PowerShell 脚本或命令。
  • Add-Type -Path ".\xxx.dll":用于引入第三方dll
  • New-Object HtmlAgilityPack.HtmlDocument:用于创建引入的库中的对象
    • HtmlAgilityPack:用于解析html文本的第三方库
    • 官网:https://github.com/zzzprojects/html-agility-pack/releases/tag/v1.11.61
    • 下载源码后,手动编译 HtmlAgilityPack.Net40,得到 HtmlAgilityPack.dll
  • .DocumentNode.SelectSingleNode:用于配合XPATH语法解析html文本
  • [System.Uri]::EscapeDataString($搜索关键词)
    • 搜索的关键字是中文,实际发送请求时,需要把中文转换

三. 代码

param(
    # 参数必须输入
    [Parameter(Mandatory)]
    # 当未添加 -name 参数时,脚本会报错
    [string]$搜索关键词
)

# 域名
$domain = 'http://www.kisssub.org'
# 搜索关键字,通过 [System.Uri]::EscapeDataString 对汉字进行编码
$enCoded_search_keyword = [System.Uri]::EscapeDataString($搜索关键词)
# 请求地址
$request_url = "$($domain)/search.php?keyword=$($enCoded_search_keyword)"

# session
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$session.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36"
$session.Cookies.Add((New-Object System.Net.Cookie("user_script_url", "%2F%2F1.acgscript.com%2Fscript%2Fmiobt%2F4.js%3F3", "/", "www.kisssub.org")))
$session.Cookies.Add((New-Object System.Net.Cookie("user_script_rev", "20181120.2", "/", "www.kisssub.org")))

# 请求头
$request_header = @{
    "Accept"="text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
    "Accept-Encoding"="gzip, deflate"
    "Accept-Language"="zh-CN,zh;q=0.9,ja;q=0.8,en;q=0.7,zh-TW;q=0.6"
    "Cache-Control"="no-cache"
    "Pragma"="no-cache"
    "Upgrade-Insecure-Requests"="1"
}

# 获取磁力链接所在页面的URL
function Get_WEB_URL {

    param (
        [string]$url
        , [Microsoft.PowerShell.Commands.WebRequestSession]$session
        , [PSCustomObject]$header
    )

    # 发送网络请求
    $response = Invoke-WebRequest -UseBasicParsing `
    -Uri $url `
    -WebSession $session `
    -Headers $header

    # 若响应code不是200,则证明网络连接失败
    if ($response.StatusCode -ne 200) {
        Write-Host "网络请求失败..."
        return 
    }

    # 提取磁力链接所在页面的url
    $target_web_urls = $response.Links.outerHTML | ForEach-Object {
		
		# 若不是对应页面的url,则跳过
        if (-not ($_ -match ".*show.*.html")) {
            return
        }

        # 提取出目标页面的url
        $_.split(" ")[1].replace("href=`"", "$($domain)/").replace("`"", "")
    }
    return $target_web_urls
}

# 指定url,session,header 发送网络请求
$target_web_urls = Get_WEB_URL -url $request_url -session $session -header $request_header
$target_web_urls | Out-Host

<#
    ⏹创建一个workflow,用于并发处理多任务
#>
workflow Get-WebContent {

    param (
        [string[]] $urls
    )

    <#
        ⏹foreach -parallel 是 Workflow 中用来并行处理迭代集合的语法
        每个 $url 都会并行处理,即同时发送多个请求以提高效率
    #>
    foreach -parallel ($url in $urls) {

        # 睡眠1秒
        # Start-Sleep -Seconds 1

        # ⏹InlineScript 块允许在 Workflow 中执行本地的 PowerShell 脚本或命令
        $web_response = InlineScript {
            # 发送网络请求
            $webRequest = Invoke-WebRequest -UseBasicParsing -Uri $using:url -Headers $my_header
            # 获取页面上的所有url连接
            $webRequest.Links.outerHTML
        }

        # PSCustomObject 是自定义对象的数据类型
        [PSCustomObject]@{
            Content = $web_response
        }
    }
}

Write-Host "⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓提取到的磁力链接如下⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓" -ForegroundColor Red

# 引入 HtmlAgilityPack.dll 依赖库
Add-Type -Path ".\HtmlAgilityPack.dll"
# 创建 HtmlDocument对象 用于解析html文本
$htmlDoc = New-Object HtmlAgilityPack.HtmlDocument

# 调用workflow,获取响应
$results = Get-WebContent -urls $target_web_urls
$results.Content | ForEach-Object {

    # 如果不是磁力链接的url,就跳过
    if (-not ($_ -match ".*ref=`"magnet.*")) {
        return
    }

    # 将含有磁力链接的html文本放到 HtmlDocument对象 中
    $htmlDoc.LoadHtml($_)

    <#
        ⏹通过xpath语法提取到a标签对象
        SelectSingleNode
            只能提取单节点
        SelectNodes
            可以提取多个节点
    #>
    $aEelement = $htmlDoc.DocumentNode.SelectSingleNode("//a[@id='magnet']")

    <#
        ⏹根据id获取href属性(磁力链接内容)
        第2个参数是默认参数
    #>
    $aEelement.GetAttributeValue("href", "")
} | Get-Unique

# 暂停
Pause

四. 效果

  • 只是简易爬虫,并未做IP代理池和cookie池等防反扒机制
  • 频繁使用,在一段时间内会无法访问该网站

在这里插入图片描述

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值