Python 中的动态 Web 数据库抓取



>有人知道下面的代码有什么问题吗?它只从一天中获取数据。然而,该网页是一个动态的网络数据库,包含多年的数据。我需要抓取 2013-2016 年每个月和每天的数据并存储到 CSV 文件中。

import calendar
import requests
from bs4 import BeautifulSoup
cal = calendar.Calendar()
base_url = 'http://www.pse.pl/index.php?modul=21&id_rap=24&data=2016'
month_url = '&Month='
day_url = '&Day='
for year in range(2015, 2017):
for month in range(1, 13):
monthdays = [d for d in cal.itermonthdays(year, month) if d != 0]
for day in monthdays:
r = requests.get(base_url + str(year) + month_url + str(month) + day_url + str(day))
soup = BeautifulSoup(r.text,'lxml')
findtable = soup.find('table',{'id':'tabela'})
for i in findtable.findAll('tr'):
for j in i.findAll('td'):
print (j.text)

我注意到的主要事情是,您发送到网站的 url 中的日期格式必须不同。日期元素(年、月和日(之间需要连字符。我还可以建议一种更简单的方式来度过日子。

箭头是用于处理日期的模块。在本例中,我使用它来生成从 2015 年 1 月 1 日到 2015 年 1 月 3 日(含(的天数范围。

我还用它来格式化这些日期。

我使用BeautifulSoup找到表格,然后使用熊猫将表格的内容提取到数据框中。最后,我将这些数据帧写入 csv 文件。

>>> import requests
>>> import arrow
>>> import bs4
>>> from datetime import datetime
>>> import pandas as pd
>>> start = arrow.get(datetime(2015,1,1))
>>> end = arrow.get(datetime(2015,1,3))
>>> base_url = 'http://www.pse.pl/index.php?modul=21&id_rap=24&data='
>>> for day in arrow.Arrow.range('day', start, end):
...     page = requests.get(base_url+day.format('YYYY-MM-DD')).content
...     soup = bs4.BeautifulSoup(page, 'lxml')
...     table = soup.find('table' ,{'id':'tabela'})
...     df = pd.read_html(str(table))
...     df[0].to_csv(day.format('YYYY-MM-DD')+'.csv')

您将无法使用BeautifulSoup"点击"网站。

在这种情况下,我看到 2 个选项:

1(探索selenium模块以与网站进行交互。

2( 请注意,链接的样式如下:

http://www.pse.pl/index.php?modul=21&id_rap=24&data=2017-07-19.这里的中间部分是&data=2017-07-19

您可以构建一个循环,将具体日期传递到基本链接的尾部,并使用requests打开每个此类链接。解析更进一步。

最新更新