使用python根据下拉菜单抓取更改的网页

时间:2016-03-13 15:51:33

标签: python-3.x drop-down-menu web-scraping

我一直在尝试使用python(版本3.5.1)自动从http://www.nasdaq.com/symbol/dal/historical获取数据。作为其中的一部分,我需要使用网站的下拉菜单将时间范围从默认的3个月更改为2年。来源如下:

<h4>Get up to 10 years of daily historical stock prices &amp; volumes.</h4>
<div class="floatL">
    <p>Select the Timeframe:</p>
</div>
<div class="floatL marginT10px fontS14px">
    <select id="ddlTimeFrame" name="ddlTimeFrame" onchange="getQuotes(false)">
        <option value="5d">5 Days</option>
        <option value="1m">1 Month</option>
        <option value="3m" selected="selected">3 Months</option>
        <option value="6m">6 Months</option>
        <option value="1y">1 Year</option>
        <option value="18m">18 Months</option>
        <option value="2y">2 Years</option>
        <option value="3y">3 Years</option>
        <option value="4y">4 Years</option>
        <option value="5y">5 Years</option>
        <option value="6y">6 Years</option>
        <option value="7y">7 Years</option>
        <option value="8y">8 Years</option>
        <option value="9y">9 Years</option>
        <option value="10y">10 Years</option>
    </select>
</div>
<div class="clearB"></div>
<div class="realtiveP">
    <div id="ajaxloader" class="ajax_loading_wrap" style="display:none">
        <img src="http://www.nasdaq.com/images/ajax-loader-2.gif" width="32" height="32" alt="ajax loader" />
    </div>
</div>

我已经编写了成功阅读网页的代码,但我无法从3个月更改时间范围。实际上,从列表中手动选择会更改页面而不是源。这是我使用的代码:

import urllib.request
import urllib.parse
url="http://www.nasdaq.com/symbol/dal/historical"
pageInputs={"ddlTimeFrame":"2y"}
pageGets = urllib.parse.urlencode(pageInputs)
pageGets=pageGets.encode("ascii")
serReq=urllib.request.Request(url,pageGets)
opReq=urllib.request.urlopen(serReq)
rdReq=opReq.read()
dcReq=rdReq.decode()

就像我说的那样,通过网页阅读工作正常。我需要找到一种方法来改变默认值的时间范围。

2 个答案:

答案 0 :(得分:0)

如果你只想收集数据(不是整个页面),下面是你要考虑的函数getQuotes(下载)的源代码。

function getQuotes(download) {
        if (!download)
            showLoadingSpinner();

        var data = $("[id$='ddlTimeFrame']").val();
        var submitString = data + '|' + download + "|" + quoteBoxSelectedSymbol; if (!download) {
            $.ajax({
                type: "POST",
                url: baseUrl,
                data: submitString,
                contentType: "application/json",
                success: function (response) {
                    $("[id$='historicalContainer']").html(response);
                    $(".genTable tbody tr:odd").addClass("genTablealt");
                    hideLoadingSpinner();
                }
            });
        }
        else {
            $("[id$='submitString']").val(submitString);
            $("#getFile").submit();
        }
    }

使用的实际参数:

url: "http://www.nasdaq.com/symbol/dal/historical",
data: "2y|false|DAL"

但您必须处理跨源资源共享问题,因为它们似乎拒绝来自其他主机的资源请求。

答案 1 :(得分:0)

需要注意的是onchange="getQuotes(false)"

如果您按ctrl-f&#34; getQuotes&#34;,您会找到ajax电话:

function getQuotes(download) {
    if (!download)
        showLoadingSpinner();

    var data = $("[id$='ddlTimeFrame']").val();
    var submitString = data + '|' + download + "|" + quoteBoxSelectedSymbol; if (!download) {
        $.ajax({
            type: "POST",
            url: baseUrl,
            data: submitString,
            contentType: "application/json",
            success: function (response) {
                $("[id$='historicalContainer']").html(response);
                $(".genTable tbody tr:odd").addClass("genTablealt");
                hideLoadingSpinner();
            }
        });
    }
    else {
        $("[id$='submitString']").val(submitString);
        $("#getFile").submit();
    }
}

要将AJAX调用转换为python,请参阅convert an ajax http post to python

回复将包含<tr>代码

中的数据

示例:

import requests, bs4

r = requests.post('http://www.nasdaq.com/symbol/aapl/historical',
        data='10y|false|AAPL', headers={'content-type': 'application/json'})
soup = bs4.BeautifulSoup(r.text, 'lxml')
rows = soup.select('tr')
for row in rows[1:]:
    td = row.find_all('td')
    date = td[0].text.strip()
    open = td[1].text.strip()
    high = td[2].text.strip()
    low = td[3].text.strip()
    close = td[4].text.strip()
    volume = td[5].text.strip()
    ...