使用 Python - Link 的 Web 抓取与表单输入没有变化
Webscraping using Python - Link is unchanged with form input
我计划从可用的开放网络中检索历史数据。来自 link:
https://www.entsoe.eu/db-query/consumption/mhlv-a-specific-country-for-a-specific-day
理想情况下,我尝试使用来自 Pandas 数据框的输入更改国家/地区、日、月、年并检索结果(此网页中的能源消耗)并存储回 excel。
我正在尝试使用不同的网络抓取工具,但有一条信息让我怀疑其可能性。
它是:当我手动更改国家、日、月、年和检索结果时,网络link 保持不变。是否可以通过此网站实现我的目标 link.
感谢您的宝贵时间。
首先,您需要了解单击 "Send" 按钮时会发生什么。 POST 请求被发送到同一个 URL,其参数与您在表单上选择的值相对应。您可以在浏览器开发人员工具 - "Network" 选项卡中看到此请求。现在,您需要在代码中模拟此请求(我将在下面使用很棒的 requests
package)
另一个问题是,如果您检查在对 POST 请求的响应中得到的内容,您将找不到与您在浏览器。这是因为 table
是从 script
元素中的 myData
javascript 变量 "sitting" 动态生成的。由于norBeautifiulSoup
,norrequests
不是浏览器,无法执行JavaScript,需要从脚本中提取myData
值
这是一个工作代码,可以让您在 2009 年 1 月 1 日的 "archived" 范围内获得所需的数据:
import re
from ast import literal_eval
from pprint import pprint
import requests
from bs4 import BeautifulSoup
url = "https://www.entsoe.eu/db-query/consumption/mhlv-a-specific-country-for-a-specific-day"
data = {
"opt_period": "2",
"opt_Country": "3",
"opt_Day": "1",
"opt_Month": "1",
"opt_Year": "2009",
"opt_Response": "1",
"send": "send"
}
with requests.Session() as session:
session.headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'}
# visit the page
session.get(url)
# make a POST request
response = session.post(url, data=data)
soup = BeautifulSoup(response.content, 'html.parser')
# find the desired script
pattern = re.compile(r"var myData = (.*?);", re.MULTILINE | re.DOTALL)
script = soup.find("script", text=pattern)
# extract the data from the script
match = pattern.search(script.get_text())
data = match.group(1).strip()
data = literal_eval(data)
pprint(data)
打印一个 Python 列表列表:
[['AT',
'2009-01-01',
6277,
6002,
5649,
5230,
5034,
5038,
4858,
5127,
5342,
5747,
6100,
6373,
6325,
6210,
6129,
6160,
6588,
7007,
7058,
6887,
6586,
6137,
6494,
5974]]
我计划从可用的开放网络中检索历史数据。来自 link:
https://www.entsoe.eu/db-query/consumption/mhlv-a-specific-country-for-a-specific-day
理想情况下,我尝试使用来自 Pandas 数据框的输入更改国家/地区、日、月、年并检索结果(此网页中的能源消耗)并存储回 excel。
我正在尝试使用不同的网络抓取工具,但有一条信息让我怀疑其可能性。
它是:当我手动更改国家、日、月、年和检索结果时,网络link 保持不变。是否可以通过此网站实现我的目标 link.
感谢您的宝贵时间。
首先,您需要了解单击 "Send" 按钮时会发生什么。 POST 请求被发送到同一个 URL,其参数与您在表单上选择的值相对应。您可以在浏览器开发人员工具 - "Network" 选项卡中看到此请求。现在,您需要在代码中模拟此请求(我将在下面使用很棒的 requests
package)
另一个问题是,如果您检查在对 POST 请求的响应中得到的内容,您将找不到与您在浏览器。这是因为 table
是从 script
元素中的 myData
javascript 变量 "sitting" 动态生成的。由于norBeautifiulSoup
,norrequests
不是浏览器,无法执行JavaScript,需要从脚本中提取myData
值
这是一个工作代码,可以让您在 2009 年 1 月 1 日的 "archived" 范围内获得所需的数据:
import re
from ast import literal_eval
from pprint import pprint
import requests
from bs4 import BeautifulSoup
url = "https://www.entsoe.eu/db-query/consumption/mhlv-a-specific-country-for-a-specific-day"
data = {
"opt_period": "2",
"opt_Country": "3",
"opt_Day": "1",
"opt_Month": "1",
"opt_Year": "2009",
"opt_Response": "1",
"send": "send"
}
with requests.Session() as session:
session.headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'}
# visit the page
session.get(url)
# make a POST request
response = session.post(url, data=data)
soup = BeautifulSoup(response.content, 'html.parser')
# find the desired script
pattern = re.compile(r"var myData = (.*?);", re.MULTILINE | re.DOTALL)
script = soup.find("script", text=pattern)
# extract the data from the script
match = pattern.search(script.get_text())
data = match.group(1).strip()
data = literal_eval(data)
pprint(data)
打印一个 Python 列表列表:
[['AT',
'2009-01-01',
6277,
6002,
5649,
5230,
5034,
5038,
4858,
5127,
5342,
5747,
6100,
6373,
6325,
6210,
6129,
6160,
6588,
7007,
7058,
6887,
6586,
6137,
6494,
5974]]