Python3用requests_html和BeautifulSoup抓取含select/option网页数据问题
问题排查和修正方案
核心问题点
- 表单提交数据格式错误:你构造的
data字典直接传入了BeautifulSoup解析出的标签对象,服务器只能识别键值对格式的表单参数,完全无法解析标签对象,因此请求直接无效。 - 不需要修改本地HTML属性:你在本地修改
selected属性对服务器没有任何意义,服务器仅校验你POST提交的参数值,不会读取你本地修改后的HTML代码。 - 脚本存在笔误:处理相对路径的代码中,替换script标签src属性时错误调用了
link.attrs["src"],会导致运行报错。
修正后可运行代码
from bs4 import BeautifulSoup from requests_html import HTMLSession from urllib.parse import urljoin url = "https://www.portodemanaus.com.br/?pagina=nivel-do-rio-negro-hoje" session = HTMLSession() # 先获取初始页面,提取表单所有参数(含隐藏字段) res = session.get(url) soup = BeautifulSoup(res.html.html, "html.parser") # 构造表单提交参数 form_data = {} # 先获取所有input隐藏字段,避免缺参被服务器拒绝 for input_tag in soup.find_all("input", type="hidden"): form_data[input_tag["name"]] = input_tag.get("value", "") # 补充你要查询的半年和年份:semestre=1代表上半年,ano=2018代表2018年 form_data["semestre"] = "1" form_data["ano"] = "2018" # 提交POST请求 res = session.post(url, data=form_data) soup = BeautifulSoup(res.content, "html.parser") # 替换相对路径为绝对路径 for link in soup.find_all("link"): try: link.attrs["href"] = urljoin(url, link.attrs["href"]) except: pass for script in soup.find_all("script"): try: script.attrs["src"] = urljoin(url, script.attrs["src"]) except: pass for img in soup.find_all("img"): try: img.attrs["src"] = urljoin(url, img.attrs["src"]) except: pass for a in soup.find_all("a"): try: a.attrs["href"] = urljoin(url, a.attrs["href"]) except: pass # 保存页面,指定utf-8编码避免乱码 with open("page.html", "w", encoding="utf-8") as f: f.write(str(soup))
使用说明
如果需要查询其他时间段的表格,直接修改form_data中semestre和ano的取值即可:
semestre取值为1代表上半年,取值为2代表下半年ano直接传入对应年份的字符串即可
内容的提问来源于stack exchange,提问作者Liang Guo
相关产品推荐
相关产品推荐

