使用Python通过liburl或requests提交Web表单

0 投票
3 回答
2089 浏览
提问于 2025-04-18 02:52

我正在尝试在这个网页上提交一个表单,然后想获取提交后下一个页面的HTML内容。我发现可以用requests或者liburl这两种方法来实现。

import urllib
import urllib2
import webbrowser

url = 'https://fcq.colorado.edu/UCBdata.htm'

def main():
    data = urllib.urlencode({'subj': 'CSCI', 'crse': '1300'})
    results = urllib2.urlopen(url, data)
    print results.read()
    with open("results.html", "w") as f:
        f.write(results.read())

    webbrowser.open("results.html")
    return 0

 if __name__ == '__main__':
    main()

或者:

import requests

url = 'https://fcq.colorado.edu/UCBdata.htm'

def main():     
    payload = {'subj': 'CSCI', 'crse': '1300'}
    r = requests.post(url, payload)
    with open("requests_results.html", "w") as f:
        f.write(r.content)  
    return 0

if __name__ == '__main__':
    main()

但是,当我请求到页面后,得到的却还是同一个包含表单的页面。这让我在想,是不是和提交按钮有关?我对网页和Python都很陌生,所以任何建议或想法都非常感谢!谢谢!

这是提交按钮的HTML代码:

<input type="submit" name="sub" value="Submit Request" onclick="this.disabled=true,this.form.submit();">

3 个回答

0

我不知道你是否还感兴趣,但我其实做过类似的事情,处理的也是同样的问题。我使用了Mechanize和Requests这两个库,创建了一个类似于Python爬虫的API。

你可以在github上查看我的代码,如果你觉得可以做得更好,欢迎提出改进建议。

0

这个表单的目标网址是 https://fcq.colorado.edu/scripts/broker.exe(可以在 <form> 标签的 action 属性中找到)。所以你需要把:

url = 'https://fcq.colorado.edu/UCBdata.htm'

替换成

url = 'https://fcq.colorado.edu/scripts/broker.exe'
2

这个页面上的表单实际上是通过JavaScript提交的,所以光看这个 <form /> 元素是不够的。你可以使用比如 Firebug 的网络标签,或者Chrome的开发者工具,在你提交表单后检查一下POST请求,这样就能看到实际提交了什么内容。

这个方法似乎有效:

import requests

url = 'https://fcq.colorado.edu/scripts/broker.exe'

payload = {
    "_PROGRAM": "fcqlib.fcqdata.sas",
    "_SERVICE": "fcq",
    "camp": "BD",
    "fileFrmt": "HTM",
    "ftrm": "1",
    "fyr": "2007",
    "grp1": "ALL",
    "jjj": "mytst",
    "ltrm": "7",
    "lyr": "2013",
    "sort": "descending YEARTERM SUBJECT COURSE SECTION",
}

payload.update({
    'subj': 'CSCI',
    'crse': '1300',
})


def main():
    r = requests.post(url, payload)
    with open("requests_results.html", "w") as f:
        f.write(r.content)
    return 0

if __name__ == '__main__':
    main()

撰写回答