【问题标题】:Regex isn't recognized in a curl/grep combination在 curl/grep 组合中无法识别正则表达式
【发布时间】:2021-06-21 13:50:02
【问题描述】:

我尝试使用以下 curl/grep/seed 组合从 html url 列表中获取图像 url(wget 我失败了 403,但cUrl 正确获取源代码):

curl -K "C:\urls.txt" | "C:\GnuWin32\bin\grep.exe" -o '(http[^\s]+(jpg|png|webp)\b)' | sed 's/\?.*//' > imglinks.txt

但我收到一个错误The command "png" is either misspelled or could not be found.

正则表达式应该是正确的:https://regex101.com/r/Qk6A0Z/1/

如何改进这段代码?

编辑:我的列表中单个url的源代码可以看到运行curl https://watchbase.com/sellita

sn-p,我想从中获取图片网址的样子

<picture>
<source type="image/webp" data-srcset="https://cdn.watchbase.com/caliber/md/origin:png/sellita/sw200-1-bd.webp" srcset="https://assets.watchbase.com/img/FFFFFF-0.png" />
<img class="lazyload" data-src="https://cdn.watchbase.com/caliber/md/sellita/sw200-1-bd.png" src="https://assets.watchbase.com/img/FFFFFF-0.png" alt="Sellita caliber SW200-1"/>
</picture>

预期的输出是一个包含所有图像 url 的文件,即使是来自 data-srcdata-srcset 的文件。

【问题讨论】:

  • 你做的很不对,为什么要用curl -K 'C:\urls.txt' | grep -o pattern?你可以简单地使用"C:\GnuWin32\bin\grep.exe" -oP "http[^?\s]+(jpg|png|webp)\b" "C:\urls.txt" &gt; imglinks.txt
  • 这样我只得到空文件imglinks.txt。如果我使用单个 url 而不是文件列表,例如 "C:\GnuWin32\bin\grep.exe" -oP "http[^?\s]+(jpg|png|webp)\b" https://watchbase.com/sellita &gt; imglinks.txt 我得到 no such file or directory
  • 您能否显示您的curl 命令的输出并显示您预期的最终输出。
  • 刚刚试过,"C:\GnuWin32\bin\grep.exe" -oE "http[^?[:space:]]+(jpg|png|webp)\b" "C:\urls.txt" 效果很好。同"C:\GnuWin32\bin\grep.exe" -oP "http[^?\s]+(jpg|png|webp)\b" "C:\urls.txt"
  • 无论如何,'png' is not recognized as an internal or external command, operable program or batch file 问题是由于使用了单引号引起的。使用双倍。

标签: regex windows curl sed grep


【解决方案1】:

你可以试试这个xargs+curl+grep 管道:

xargs -n 1 curl < "C:\urls.txt" | "C:\GnuWin32\bin\grep.exe" -Eo "http[^[:blank:]?'\"]+(jpe?g|png|gif|bmp|ico|tiff|webp)\b" > imglinks.txt

【讨论】:

  • 这条线工作xargs curl &lt; "C:\urls.txt" | "C:\GnuWin32\bin\grep.exe" -Eo "http[^?[:space:]]+(jpg|png|webp)\b" &gt; imglinks.txt,但是从文件urls.txt中包含的33.000个url中只处理了10个url。
  • 当然,我有。从这里:gnuwin32.sourceforge.net/packages/findutils.htm
  • 试试这个:xargs -n 1 curl &lt; "C:\urls.txt" | "C:\GnuWin32\bin\grep.exe" -Eo "http[^?[:space:]]+(jpg|png|webp)\b" &gt; imglinks.txt
  • 无论如何,xargs 命令没有限制在 82 或 100 之后停止,除非该系统有一些外部限制。我已经使用xargs 处理了数百万行。
  • while 在我的 Windows 上不起作用。我在另一个网络中的另一台机器上测试了xargs -n 1 curl &lt; "C:\urls.txt" | "C:\GnuWin32\bin\grep.exe" -Eo "http[^?[:space:]]+(jpg|png|webp)\b" &gt; imglinks.txt - 它在恰好 82 个 url 之后再次停止。
【解决方案2】:

你可以使用

curl "https://watchbase.com/sellita"  | "C:\GnuWin32\bin\grep.exe" -oE "http[^?[:space:]]+(jpg|png|webp)\b"  > imglinks.txt

'png' is not recognized as an internal or external command, operable program or batch file 问题是由于使用了单引号引起的。您应该在 Windows 中使用双引号 grep

要从文件中读取所有 URL 并处理它们,您可以使用

FOR /F %i in (C:\urls.txt) DO curl %i | "C:\GnuWin32\bin\grep.exe" -oP "http[^?\s]+(jpg|png|webp)\b" >> imglinks.txt

【讨论】:

  • 是的,它确实有效!是否有可能使用带有 url 列表而不是单个 url 的文件?我尝试了curl "C:\urls.txt"-K - 但两者都没有运气......
  • @Evgeniy 我已经分享过了:"C:\GnuWin32\bin\grep.exe" -oE "http[^?[:space:]]+(jpg|png|webp)\b" "C:\urls.txt" &gt; imglinks.txt。您应该将文件路径直接传递给grep
  • 这样我得到的只是空的imglinks.txt
  • @Evgeniy 见this demo screenshot,它工作正常。
  • @Evgeniy “进入另一个 txt 文件” - 这已经解决了。 FOR /F %i in (C:\1\1.txt) DO ("c:\Program Files\Git\mingw64\bin\curl.exe" %i | "c:\Program Files (x86)\GnuWin32\bin\grep.exe" -oP "http[^?\s]+(jpg|png|webp)\b" &gt;&gt; imglinks.txt)(我最终执行)将网页上找到的所有链接(在C:\1\1.txt 文件中列出)写入imglinks.txt 文件中。
【解决方案3】:

尝试使用 RegEX 解析 HTML 是非常糟糕的做法!看到高级成员甚至鼓励这样做真的让我想哭。这样一来,这些问题的源源不断的洪水就永远不会结束。

请看:

要解析 HTML,请使用 HTML 解析器,例如

<picture>
<source type="image/webp" data-srcset="https://cdn.watchbase.com/caliber/md/origin:png/sellita/sw200-1-bd.webp" srcset="https://assets.watchbase.com/img/FFFFFF-0.png" />
<img class="lazyload" data-src="https://cdn.watchbase.com/caliber/md/sellita/sw200-1-bd.png" src="https://assets.watchbase.com/img/FFFFFF-0.png" alt="Sellita caliber SW200-1"/>
</picture>

https://assets.watchbase.com/img/FFFFFF-0.png 只是 1 个白色像素,并在每个 &lt;picture&gt;-node 中返回。所以我假设你只想要属性data-srcsetdata-src

xidel -s "https://watchbase.com/sellita" -e "//picture/(source/@data-srcset,img/@data-src)"

您还可以使用 xidel(只需 1 次调用)来处理您在 "C:\urls.txt" 中的网址(假设它们都具有与 https://watchbase.com/sellita 相同的 &lt;picture&gt;-nodes)。

xidel -s "C:\urls.txt" -e "for $url in x:lines($raw) return doc($url)//picture/(source/@data-srcset,img/@data-src)" > imglinks.txt

xidel -se "for $url in file:read-text-lines('C:\urls.txt') return doc($url)//picture/(source/@data-srcset,img/@data-src)" > imglinks.txt

如果您的目标是从 'imglinks.txt' 下载所有图片,那么 xidel 也可以这样做。

xidel -s "C:\urls.txt" -f "for $url in x:lines($raw) return doc($url)//picture/(source/@data-srcset,img/@data-src)" --download "."

xidel -s --xquery "for $url in file:read-text-lines('C:\urls.txt') for $img in doc($url)//picture/(source/@data-srcset,img/@data-src) return file:write-binary(tokenize($img,'/')[last()],string-to-base64Binary(x:request($img)/raw))"

xidel -s --xquery ^"^
  for $url in file:read-text-lines('C:\urls.txt')^
  for $img in doc($url)//picture/(source/@data-srcset,img/@data-src)^
  return^
  file:write-binary(^
    tokenize($img,'/')[last()],^
    string-to-base64Binary(x:request($img)/raw)^
  )^
"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-04
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    相关资源
    最近更新 更多