Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何正确使用POST请求?_Python_Python 3.x_Web Scraping_Beautifulsoup_Http Post - Fatal编程技术网

Python 如何正确使用POST请求?

Python 如何正确使用POST请求?,python,python-3.x,web-scraping,beautifulsoup,http-post,Python,Python 3.x,Web Scraping,Beautifulsoup,Http Post,我已经写了一些代码从网页中获取数据。该网站有下拉选项来选择更可取的项目。因此,首先我提出了一个GET请求来形成url,然后是一个POST请求。我只解析了第一页的数据,但填充的结果显示在多个页面上。当我在表单数据参数中更改页码时,它对结果没有任何影响。我仍然从第一页得到结果。我怎样才能把它们都买下来?顺便说一句,我没有根据自己的喜好从下拉选项中选择任何内容;相反,我启动了一个搜索,搜索默认首选项是如何设置的 链接到该网站: 这就是我迄今为止所尝试的: import requests from bs

我已经写了一些代码从网页中获取数据。该网站有下拉选项来选择更可取的项目。因此,首先我提出了一个
GET
请求来形成url,然后是一个
POST
请求。我只解析了第一页的数据,但填充的结果显示在多个页面上。当我在表单数据参数中更改页码时,它对结果没有任何影响。我仍然从第一页得到结果。我怎样才能把它们都买下来?顺便说一句,我没有根据自己的喜好从下拉选项中选择任何内容;相反,我启动了一个搜索,搜索默认首选项是如何设置的

链接到该网站:

这就是我迄今为止所尝试的:

import requests
from bs4 import BeautifulSoup

payload={

    's':'opportunity',
    'mode':'list',
    'tab':'list',
    'pageID':3
}

r = requests.get("replace_with_above_url",params=payload,headers={'User-Agent':'Mozilla/5.0'})

payload={

    'dnf_class_values[procurement_notice][_posted_date]':'90',
    'dnf_class_values[procurement_notice][set_aside][]':'',
    'dnf_class_values[procurement_notice][zipstate]':'',
    'dnf_class_values[procurement_notice][procurement_type][]':'',
    'dnf_class_values[procurement_notice][keywords]':'',
    'autocomplete_input_dnf_class_values[procurement_notice][agency]':'',
    'dnf_class_values[procurement_notice][agency]':'',
    'so_form_prefix':'dnf_',
    'dnf_opt_action':'search',
    'dnf_opt_template':'vendor_procurement_notice_filter',
    'dnf_opt_mode':'update',
    'dnf_opt_finalize':'0',
    'dnf_opt_target':'',
    'dnf_opt_validate':'1',
    'dnf_class_values[procurement_notice][dnf_class_name]':'procurement_notice',
    'clear_filters_from_home':'1'   
}

res = requests.post(r.url,data=payload, headers={'User-Agent':'Mozilla/5.0'})
soup = BeautifulSoup(res.text,"lxml")
for item in soup.select(".solt"):
    print(item.text)

通过web控制台查看站点时发现,点击“搜索”按钮会发出一个包含查询字符串和表单数据参数的POST请求,而单击下面的页面定位点则会启动一个GET请求,仅包含查询字符串(并相应地设置了pageID参数)

我编辑了您的代码,添加了一个
run
函数,该函数将pageid作为
page
参数,如果
page
等于1,则发出一条POST,否则返回GET:

import requests
from bs4 import BeautifulSoup

payload={

    'dnf_class_values[procurement_notice][_posted_date]':'90',
    'dnf_class_values[procurement_notice][set_aside][]':'',
    'dnf_class_values[procurement_notice][zipstate]':'',
    'dnf_class_values[procurement_notice][procurement_type][]':'',
    'dnf_class_values[procurement_notice][keywords]':'',
    'autocomplete_input_dnf_class_values[procurement_notice][agency]':'',
    'dnf_class_values[procurement_notice][agency]':'',
    'so_form_prefix':'dnf_',
    'dnf_opt_action':'search',
    'dnf_opt_template':'vendor_procurement_notice_filter',
    'dnf_opt_mode':'update',
    'dnf_opt_finalize':'0',
    'dnf_opt_target':'',
    'dnf_opt_validate':'1',
    'dnf_class_values[procurement_notice][dnf_class_name]':'procurement_notice',
    'clear_filters_from_home':'1',
}
def run(page):
    url = "the given url"
    query = {
        's': 'opportunity',
        'mode': 'list',
        'tab': 'list',
        'pageID': page
    }
    if(page==1):
        r = requests.get(url, params=query, headers={'User-Agent': 'Mozilla/5.0'})
        res = requests.post(r.url,data=payload, headers={'User-Agent':'Mozilla/5.0'})
    else:
        res = requests.get(url, params=query, headers={'User-Agent': 'Mozilla/5.0'})
    soup = BeautifulSoup(res.text,"lxml")
    for item in soup.select(".solt"):
        print(item.text)

for page in range(10):
    run(page + 1)

此代码包含200行,即10页,每页20个结果。

服务器使用会话cookie“记住”您的搜索。您的代码将丢弃服务器返回的所有cookie,因此每次发出新请求时都会重置内存

使用a记录传入的Cookie,并在后续请求中再次发送它们:

with requests.Session() as sess:
    sess.headers['User-Agent'] = 'Mozilla/5.0'
    r = sess.get("replace_with_above_url", params=payload)

    # ...

    res = sess.post(r.url, data=payload)
然后,您可以提交
GET
/index?s=opportunity&mode=list&tab=list&pageID=
URL的请求,这些URL的数字页面ID从
1开始,直到遇到空结果集:

page_id = 0
page_url = 'https://www.fbo.gov/index?s=opportunity&mode=list&tab=list&pageID={}'
while True:
    page_id += 1 
    page = sess.get(page_url.format(page_id))
    soup = BeautifulSoup(page.text, "lxml")
    rows = soup.select('.solr-lst table tr')
    if len(rows) <= 1:
        break
    for row in rows[1:]:
        print([c.get_text(strip=True) for c in rows[1].select('td')])
page\u id=0
第页https://www.fbo.gov/index?s=opportunity&mode=list&tab=list&pageID={}'
尽管如此:
页面id+=1
page=sess.get(page\url.format(page\id))
汤=美汤(page.text,“lxml”)
行=汤。选择('.solr lst table tr')

如果莱恩(rows)感谢Martijn Pieters爵士的回答。你很接近。我得到了很多复制品。我不知道它是否是因为我的脚本而生成的。然而,我在这里粘贴了一个链接,你可以在这里看到我试图组织你建议的部分去尝试。只要给我一些建议,看看我是否做了相应的事情,或者任何事情都应该在
块之外。最后一个问题是,如果不是行,那么这个
:按照我在脚本中使用的方式断开
部分。谢谢这是链接:@Topto:恐怕这个链接实际上没有什么意义。@Topto:我已经调整了最后一页的检测;空页至少有一行(带页眉)。对不起,先生。现在看看。我希望它现在能工作:@Topto:
res
只是HTTP POST请求的响应对象。使用它来验证请求是否成功,或者只是不分配它而不使用它。