在 python 中结合 cd && curl

Posted

技术标签:

【中文标题】在 python 中结合 cd && curl【英文标题】:combine cd && curl in python 【发布时间】:2019-06-14 03:20:32 【问题描述】:

这是我用来从网站下载 pdf 的工具。 当我不结合 cd.... && 部分时,curl 启动并下载文件。 但是,每当我使用 cd 命令更改目录并下载文件时,它只是通过 curl 命令。 我不想为 curl 提供 -o 参数,因为我不愿意为文件提供自定义名称。 请提出此问题的原因和解决方案。

这个问题是独一无二的,因为它要求使用 bash 命令实现 curl。建议的线程仅与 bash 命令有关。

import subprocess
import shlex

url = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
sessionID = input('Please, enter jsessionid...\n')
sessionID = str(sessionID) # Cookies
cookies_from_function = " -H 'Cookie: rppValue=20; B_View=1; JSESSIONID=" + sessionID + "'"
tempstring =  '-L -O -C - ' + url + " -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:64.0) Gecko/20100101 Firefox/64.0' -H 'Accept: */*' --compressed -H 'Connection: keep-alive'" + cookies_from_function# Login To Browser, inspect element, go to network tab, reload, copy curl url for a pdf link. Extract headers with cookies and paste here.
# print(tempstring)
curl_cmd = "cd /Volumes/path/to/destination/ && curl " + tempstring# Original
subprocess.call(shlex.split(curl_cmd))

【问题讨论】:

再次查看subprocess.call()。一般地传递​​参数并针对您的问题特别查看cwd 关键字参数。更好的是,urllib 不必费心执行任何其他操作。 Save file to specific folder with curl command的可能重复 @MarcinOrlowski 该链接仅谈论 bash。这是python+bash。 【参考方案1】:

&& 是一个 shell 逻辑运算符,用于在前一个命令成功时运行命令。所以,你需要在 shell 中运行它;使用shell=True 并将其作为字符串而不是列表传递:

subprocess.call(curl_cmd, shell=True)

直接在 shell 中运行命令,除非经过清理可能会产生灾难性的影响。

附带说明一下,您应该考虑使用os 和一些网络客户端(例如)直接在 Python 中执行操作。 requests.


另外,如果您不想使用curl-o 选项,可以使用shell 重定向运算符(>)将curl 的STDOUT 保存到某个文件:

curl -s ... >/out/file

-s 使curl 沉默,这样我们就不会在 STDERR 上获得进度状态。

【讨论】:

谢谢,这解决了问题。我必须在更复杂的任务中使用它。我希望它有效。对于,请求图书馆,我的知识是有限的。我不想拥有恢复功能,所以首先要考虑 cUrl。对于请求,我可能需要获取标题,然后与特定目录中的同名文件进行比较等。如果我要求不高,请分享您对该过程的见解,包括请求库和一些指导链接。再次感谢。 在我的复杂项目中,我不得不移除 shlex 部分。即使添加了 shell 参数,这也会导致问题。 @lalitaalaalitah 请参阅docs.python-requests.org/en/master/user/quickstart .requests 就可用而言非常简单。请浏览快速入门,如果您在理解某些内容时遇到任何问题,请告诉我。祝你好运! 我尝试使用请求,但重定向超出限制,即使超出。也尝试设置会话。 @lalitaalaalitah 好的。您应该将详细信息添加到您的问题中,并选择另一个作为更完整的接受。我将删除我的答案,因为现在问题似乎有所不同。【参考方案2】:

正如评论中所建议的,您可以使用subprocess 函数的cwd 关键字参数在不同的目录中运行。另一个简单的选择是open 一个合适的文件并将其作为stdout 传递给subprocess 调用。

切线,您可能想要使用check_call 或现代替代品run,而不是非常基本的call

import subprocess
import os

url = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
sessionID = input('Please, enter jsessionid...\n')
# No need, input aways returns a string in Python 3
# sessionID = str(sessionID) # Cookies
with open(os.path.join('/Volumes/path/to/destination', 'dummy.pdf')) as pdf:
    subprocess.check_call([
            'curl', '-L', '-C', '-', url,
            '-H', 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:64.0) Gecko/20100101 Firefox/64.0',
            '-H', 'Accept: */*', '--compressed',
            '-H', 'Connection: keep-alive',
            '-H', 'Cookie: rppValue=20; B_View=1; JSESSIONID=0'.format(sessionID)],
          stdout=pdf)

这也取消了shlex,部分原因是您在评论中说您必须摆脱它,部分原因是与手动将简单的静态命令行拆分为令牌一次相比,它并没有真正提供任何重要价值(虽然你必须明白如何去做,很明显)。

如果您想保留-O 选项,

subprocess.check_call([
    'curl', '-O', ...],
    cwd='/Volumes/path/to/destination')

【讨论】:

我会试着检查一下。但是,它不是假设我必须提供文件名吗?如果是,有什么方法可以摆脱它并使用服务器提供的文件名? 那么可能是前面提到的cwd 技巧。我会更新另一个版本。 另见***.com/a/51950538/874188 了解更多关于子进程和常见反模式的信息。 (之前尝试链接但放错链接,对不起。) 出于某些原因 subprocess.check_call(['curl', '-O', ...],cwd='/Volumes/path/to/destination')下载一些 html 而不是 pdf 但是在检查下提供 cd 命令没有任何问题。

以上是关于在 python 中结合 cd && curl的主要内容,如果未能解决你的问题,请参考以下文章

如何在notepad++中执行python脚本?

Python 基于Python结合pykafka实现kafka生产及消费速率&主题分区偏移实时监控

python2.7.8安装

树莓GPIO &&python

在 Google colab 中更改目录(脱离 python 解释器)

Notepad++ 运行脚本快捷键设置