当前位置:   article > 正文

powershell 配合aria2实现简单的图片爬取

powershell 配合aria2实现简单的图片爬取

powershell 配合aria2实现简单的图片爬取

01 前言

现如今,提到爬虫,令人不得不提到Python,确实简单,也强大,到处都可以找到教程。故而今天换换口味,用powershell来实现,配合aria2的强大下载功能,也很nice

02 正文

测试环境:Windows 11

1. 确定目标网站

这一步通过搜索引擎,很容易就可以找到感兴趣的网站,此处略。

2. 确定有订阅源地址

假设目标网站为:https://abc.com,然后在地址栏后面加:/feed,回车访问(即完整的路径为:https://abc.com/feed)。
如果能够正常访问,且有内容(XML格式),那可以,比如大概长这样:
xml

3. 开始处理

为了方便使用,分为两个部分:powershell脚本bat脚本,那么通过修改bat脚本参数,可以双击直接运行。

(1)首先应该有aria2,【下载】好并解压。如果本机已经有,就不必下载了。

(2)powershell脚本代码



<#
    xml解析图片地址,调用aria2下载

    by hokis

    2024-05-29 19:36

#>

[CmdletBinding()]
Param
(
    # 域名,一般以/结尾,如:https://abc.com/
    [Parameter(Mandatory=$true,
                ValueFromPipelineByPropertyName=$true,
                Position=0)]
    [string]
    $server,

    #保存路径,如果为空,则放在 我的/图片 下
    [string]
    $savePath = '',

    #aria2.exe所在目录
    [Parameter(Mandatory=$true)]
    [string]
    $aria2Path
)


function Invoke-DownWithAria2
{
    [CmdletBinding()]
    Param
    (
        # 文件列表,格式:ArrayList 里面放一个2个元素的数组,第一个是URL,第二个是文件名
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [System.Collections.ArrayList]
        $fileList,

        #referer
        [string]
        $refer,

        [string]
        $newSavePath,

        #aria2路径
        [string]
        $aria2Path = ''
    )

    Begin
    {

    }
    Process
    {
                #配置模板
        $conf = @'

## 日志
log-level=error
#log=/PATH/.aria2/aria2.log

#控制台日志
console-log-level=error

## 文件保存相关 ##
 
# 文件保存目录
#dir=
{0}
# 启用磁盘缓存, 0为禁用缓存, 需1.16以上版本, 默认:16M
disk-cache=32M
# 断点续传
continue=true
 
# 文件预分配方式, 能有效降低磁盘碎片, 默认:prealloc
# 预分配所需时间: none < falloc ? trunc < prealloc
# falloc和trunc则需要文件系统和内核支持
# NTFS建议使用falloc, EXT3/4建议trunc, MAC 下需要注释此项
file-allocation=falloc
 
## 下载连接相关 ##

# 最大同时下载任务数, 运行时可修改, 默认:5
max-concurrent-downloads=10
# 整体下载速度限制, 运行时可修改, 默认:0(不限制)
max-overall-download-limit=0
# 单个任务下载速度限制, 默认:0(不限制)
#max-download-limit=0
# 整体上传速度限制, 运行时可修改, 默认:0(不限制)
#max-overall-upload-limit=0
# 单个任务上传速度限制, 默认:0(不限制)
#max-upload-limit=0
# 禁用IPv6, 默认:false
disable-ipv6=true

# 客户端伪装
user-agent=Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
#referer=
{1}

# 最小文件分片大小, 添加时可指定, 取值范围1M -1024M, 默认:20M
# 假定size=10M, 文件为20MiB 则使用两个来源下载; 文件为15MiB 则使用一个来源下载
min-split-size=10M
# 单个任务最大线程数, 添加时可指定, 默认:5
# 建议同max-connection-per-server设置为相同值
split=20
 
# 读取下载任务
#input-file=
{2}

'@
        
        if(-not $fileList -or $fileList.Count -lt 1){
            Write-Warning 'file should not be null'
            return
        }

        $tempFName = [System.IO.Path]::GetRandomFileName()
        $tempDownFile = Join-Path -Path $env:TEMP -ChildPath $tempFName

        Write-Verbose ('down file :' + $tempDownFile)

        $sb = [System.Text.StringBuilder]::new()

        foreach($f in $fileList){
            #如果不是标准的http或https开头,则不处理
            if(-not $f[0].StartsWith('http://') -and -not $f[0].StartsWith('https://')){
                continue
            }
            [void]$sb.AppendLine($f[0]).AppendLine(' dir='+($f[1] -replace '\\','/')).AppendLine(' out='+$f[2])
        }

        [System.IO.File]::WriteAllText($tempDownFile,$sb.ToString(),[System.Text.UTF8Encoding]::new($false))


        $referStr = ''
        if(-not [string]::IsNullOrEmpty($refer)){
            $referStr = ('referer={0}' -f $refer)
        }

        $inputStr = ('input-file={0}' -f ($tempDownFile -replace '\\','/'))
        
        $pathStr = ('dir={0}' -f ($newSavePath -replace '\\','/'))

        $newConf = ($conf -f $pathStr,$referStr,$inputStr)

        $tempFName = ([System.IO.Path]::GetRandomFileName() -split '\.')[0]
        $tempConfFile = Join-Path -Path $env:TEMP -ChildPath ($tempFName+'.conf')

        Write-Verbose ('down conf :' + $tempConfFile)

        [System.IO.File]::WriteAllText($tempConfFile,$newConf,[System.Text.UTF8Encoding]::new($false))
        
        $aria2File = Join-Path -Path $aria2Path -ChildPath 'aria2c.exe'
        if((Test-Path -Path $aria2File -PathType Leaf)){
            $cmdStr = ('"{0}" --conf-path="{1}" --quiet' -f $aria2File,($tempConfFile -replace '\\','/'))
            Write-Verbose ("cmd:" + $cmdStr)
            &cmd.exe /c $cmdStr
        }

        #移除文件
        Remove-Item -Path $tempConfFile -Force | Out-Null
        Remove-Item -Path $tempDownFile -Force | Out-Null
    }
    End
    {
    }
}


#验证参数
if([string]::IsNullOrEmpty($server)){
    Write-Host 'Invalid server...'
    exit
}


if([string]::IsNullOrEmpty($aria2Path)){
    Write-Host 'Invalid aria2Path...'
    exit
}


if(-not (Test-Path -Path $aria2Path -PathType Container)){
    Write-Host 'Not exists aria2Path...'
    exit
}


#保存路径
if([string]::IsNullOrEmpty($savePath)){
    #保存在 图片 下
    $savePath = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::MyPictures)
}


#域名
if(-not $server.EndsWith('/')){
    $server += '/'
}

#xml网址,默认是 /feed
$xmlUrl = $server+'feed'

#图片正则,根据情况进行修改
$reg = [System.Text.RegularExpressions.Regex]::new('<figure.*?<img.*?src=["''](.*?)["''].*?/><\/figure>')

#日期
$ts = Get-Date -Format 'yyyy-MM-dd'

#以日期命名的目录
$newSavePath = Join-Path -Path $savePath -ChildPath $ts

#创建目录
if(-not (Test-Path -Path $newSavePath -PathType Container)){
    mkdir -Path $newSavePath -Force | Out-Null
}

$resp = Invoke-RestMethod -Uri $xmlUrl

if(-not $resp){
    Write-Host 'Get page error...'
    exit
}


#数据
$list = [System.Collections.ArrayList]::new()

Write-Host 'Parsing data...'

#文件名中的非法字符
$chs = [System.IO.Path]::GetInvalidFileNameChars()

#遍历
foreach($item in $resp){
    #标题
    $title = $item.title
    #内容
    $str = $item.encoded.'#cdata-section'
    #匹配
    $ms = $reg.Matches($str)

    if($ms -and $ms.Count -gt 0){
            
        #每个item有自己的名称

        #去掉非法字符
        foreach($c in $chs){
            $title = $title.Replace($c,[char]32)
        }

        #以标题创建文件夹
        $curPath = Join-Path $newSavePath -ChildPath $title

        #序号
        $idx = 0
        #[System.Text.RegularExpressions.Match]$m = $null
        foreach($m in $ms){
            #生成一个guid
            $gid = ([guid]::NewGuid().ToString() -replace '\-','')

            #捕获分组
            $url = $m.Groups[1].ToString().Trim()

            #后缀名
            $ext = ($url -split '\.')[-1]

            #文件名
            $baseName =('{0}_{1}.{2}' -f $idx,$gid,$ext)
            
            [void]$list.Add(@($url,$curPath,$baseName))

            $idx++
        }
    }else{
        Write-Host ('【{0}】No matches...' -f $title)
    }

}

if($list.Count -gt 0){
    Write-Host 'Start to download...'
    #开始下载
    Invoke-DownWithAria2 -fileList $list -refer $server -newSavePath $newSavePath -aria2Path $aria2Path

}else{
    Write-Host 'No match data...'
}


Write-Host ('Done at:' + (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'))

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302

注意:

  • 代码另存为 parse-xml.ps1,假设全路径为:C:\script\parse-xml.ps1,需注意修改bat脚本中的对应路径
  • 匹配图片路径是通过正则来的,需要根据不同的实际情况进行修改,应确保图片路径在第1个分组的位置:
    $reg = [System.Text.RegularExpressions.Regex]::new(‘<figure.*?<img.*?src=["''](.*?)["''].*?/><\/figure>’)
  • aria2是临时生成的配置,下载完成后会自动删除,不会影响原来的配置。

(3)bat脚本部分

@echo off
chcp 65001
title 图片下载
REM cls
REM 目标网址
set server=https://abc.com/
REM aria2所在路径
set aria2Path=C:\aria2
REM 图片保存路径(可以为空,空则保存到 我的/图片 下)
REM set savePath=
set savePath=C:\Down
echo.
REM 注意修改.ps1 文件全路径
powershell.exe -file "C:\script\parse-xml.ps1" -server "%server%" -aria2Path "%aria2Path%" -savePath "%savePath%"
echo.
echo.

pause
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

使用脚本注意:

  • 需修改目标网站aria2所在路径图片保存路径
  • 代码另存为 run.bat,双击运行即可
  • 运行成功后,会在图片保存路径下,新增一个以当前日期命名的文件夹,所有下载的东西放在里面

运行成功:
成功

上班累了,洗把脸精神一下吧。

03 后记

仅供参考学习使用,爬虫技术慎用也。

欢迎留言交流~
------END------

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/651043
推荐阅读
相关标签
  

闽ICP备14008679号