【问题标题】:strange behaviour with curl and python requests librarycurl 和 python 请求库的奇怪行为
【发布时间】:2016-11-21 16:50:46
【问题描述】:

我试图删除这个问题——但再想我会保留它——这是一个现场演示,作为开发人员我应该更加关注细节

我正在尝试从网站获取一些数据。请求的url会查看请求的内容类型,然后做出相应的响应。

所以我尝试的 curl 命令:

curl --header "Accept: application/json, text/javascript, */*; q=0.01\r\nX-Requested-With: XMLHttpRequest\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/37.0.2062.120 Chrome/37.0.2062.120 Safari/537.36\r\n" http://www.tpex.org.tw/web/stock/margin_trading/margin_balance/margin_bal_result.php\?l\=en-us\&d\=2016/11/15\&_\=1479700586981 -v
* About to connect() to www.tpex.org.tw port 80 (#0)
*   Trying 210.63.162.130... connected
> GET /web/stock/margin_trading/margin_balance/margin_bal_result.php?l=en-us&d=2016/11/15&_=1479700586981 HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: www.tpex.org.tw
> Accept: application/json, text/javascript, */*; q=0.01\r\nX-Requested-With: XMLHttpRequest\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/37.0.2062.120 Chrome/37.0.2062.120 Safari/537.36\r\nAccept-Encoding: gzip,deflate,sdch\r\n
> 
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Date: Mon, 21 Nov 2016 07:35:56 GMT
< Server: Apache
< Content-Type: text/html; charset=utf-8
< X-Cache: MISS from localhost
< X-Cache-Lookup: MISS from localhost:3128
< Via: 1.0 localhost (squid/3.1.19)
< Connection: close
<
{"reportDate":"2016\/11\/15","iTotalRecords":610,"aaData":[["006201","YA HORNG ELECTRONIC CO.","6","0","0","0","6","0","0.09","6,361","0","0","0","0","0","0","0.0","6,361","0",""],...}

响应被截断,但基本上是 JSON。

但是,有我的 Python 代码,我认为没有太大区别。但是响应是html...

g_tpex_headers = {
    'Accept-Encoding': 'gzip,deflate,sdch',
    'Accept': 'application/json, text/javascript, */*; q=0.01',
    'User-Agent': (
        'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
        ' (KHTML, like Gecko) Ubuntu Chromium/37.0.2062.120'
        ' Chrome/37.0.2062.120 Safari/537.36'
    ),
    'X-Requested-With': 'XMLHttpRequest',
}
data_link = (
    'http://www.tpex.org.tw/web/stock/margin_trading/margin_balance/'
    'margin_bal.php?l=en-us&d={}&_=1479700586981'
)
data = []
with requests.Session() as session:
    session.headers = g_tpex_headers
    res = session.get(
        actual_data_link.format(target_dt.strftime('%Y/%m/%d'))
    )
    print(res.content[:400])

日志:

send: 'GET /web/stock/margin_trading/margin_balance/margin_bal.php?l=en-us&d=2016/11/18&_=1479700586981 HTTP/1.1\r\nHost: www.tpex.org.tw\r\nX-Requested-With: XMLHttpRequest\r\nAccept-Encoding: gzip,deflate,sdch\r\nAccept: application/json, text/javascript, */*; q=0.01\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/37.0.2062.120 Chrome/37.0.2062.120 Safari/537.36\r\n\r\n'

和回应

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title> HOME&nbsp;&gt;&nbsp;Mainboard&nbsp;&gt;&nbsp;Margin Trading&nbsp;&gt;&nbsp;Margin Balance</title>
<link rel="icon" type="image/ico" href="/web/images/favicon.ic

我看不出有什么不同。那么为什么 python 请求没有得到 JSON 响应。

【问题讨论】:

    标签: python json curl python-requests


    【解决方案1】:

    您发出请求的路径不同。在 cURL 命令中,最终路径组件是 margin_bal_result.php,而在 Python 脚本中则是 margin_bal.php。一旦您更改 Python 脚本中的路径以匹配 cURL 命令中的路径,您将获得 JSON 响应。

    更新:使用 cURL,您需要单独指定标头,而不是将它们加在一起。因此,在您的示例中,您应该使用以下命令:

    curl --header "Accept: application/json, text/javascript, */*; q=0.01" --header "X-Requested-With: XMLHttpRequest" --header "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/37.0.2062.120 Chrome/37.0.2062.120 Safari/537.36" http://www.tpex.org.tw/web/stock/margin_trading/margin_balance/margin_bal_result.php\?l\=en-us\&d\=2016/11/15\&_\=1479700586981 -v > httpres.txt
    

    这会导致发送以下请求:

    * Hostname was NOT found in DNS cache
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 210.63.162.130...
    * Connected to www.tpex.org.tw (210.63.162.130) port 80 (#0)
    > GET /web/stock/margin_trading/margin_balance/margin_bal_result.php?l=en-us&d=2016/11/15&_=1479700586981 HTTP/1.1
    > Host: www.tpex.org.tw
    > Accept: application/json, text/javascript, */*; q=0.01
    > X-Requested-With: XMLHttpRequest
    > User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/37.0.2062.120 Chrome/37.0.2062.120 Safari/537.36
    

    【讨论】:

    • 谢谢你的帮助,我太粗心了sssssssssssssssssssssssssssssssssssssssssssssssss
    • 我有一个问题,对于 curl,请注意有一行说 User-Agent 是 curl - 那行不会被发送到服务器,对吧?
    • @JunchaoGu 更新 cURL 使用结果
    【解决方案2】:

    尝试让 python 中的请求与 curl 中的请求完全一样。 你的代码:

    data_link = (
        'http://www.tpex.org.tw/web/stock/margin_trading/margin_balance/'
        'margin_bal.php?l=en-us&d={}&_=1479700586981'
    )
    

    改变了:

    data_link = (
        'http://www.tpex.org.tw/web/stock/margin_trading/margin_balance/'
        'margin_bal_result.php?l=en-us&d={}&_=1479700586981'
    )
    

    在我更正 data_link 后,我发现它确实有效。

    【讨论】:

    • ...不要认为这是关键
    • @JunchaoGu 这是我保证的关键。您在 curl 中使用 margin_bal_result.php 而在 python 代码中使用 margin_bal.php
    • @JunchaoGu 如果 HTTP 请求相同,则结果相同,使用哪个库发出请求并不重要,因为远程网站无论如何都不知道。因此,诀窍始终是使请求相同。有像 Wireshark 这样的工具,可以在发送时以原始形式检查传出的 HTTP 请求。
    • 我自己也刚刚发现了这一点。没注意到这个问题!!!我以为他们是一样的。因此浪费了两个小时。如此愚蠢的错误。无论如何感谢您的帮助
    • 我有一个问题,对于 curl,请注意有一行说 User-Agent 是 curl - 那行不会被发送到服务器,对吧?
    猜你喜欢
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    相关资源
    最近更新 更多