Python 中的动态 Web 数据库抓取
Dynamic web database scraping in Python
有人知道下面的代码有什么问题吗?它只抓取一天的数据。然而,该网页是一个动态网络数据库,包含多年的数据。我需要抓取 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)
您将无法 "click" 在现场 BeautifulSoup
。
在这种情况下,我看到了 2 个选项:
1) 探索 selenium
模块以与网站互动。
2) 注意 link 是这样的风格:
http://www.pse.pl/index.php?modul=21&id_rap=24&data=2017-07-19
。这里有趣的部分是 &data=2017-07-19
您可以构建一个循环,将具体日期传递到基数 link 的尾部,然后用 requests
打开每个这样的 link。解析更进一步。
我注意到的主要事情是,您发送到网站的 url 中的日期格式必须不同。日期元素(年、月和日)之间需要连字符。我还可以建议一种更简单的方式来度过每一天。
Arrows 是一个处理日期的模块。在这种情况下,我使用它来生成从 2015 年 1 月 1 日到 2015 年 1 月 3 日(含)的日期范围。
我也用它来格式化这些日期。
我使用 BeautifulSoup 找到表格,然后使用 pandas 将表格的内容提取到数据框中。最后,我将这些数据帧写入 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')
有人知道下面的代码有什么问题吗?它只抓取一天的数据。然而,该网页是一个动态网络数据库,包含多年的数据。我需要抓取 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)
您将无法 "click" 在现场 BeautifulSoup
。
在这种情况下,我看到了 2 个选项:
1) 探索 selenium
模块以与网站互动。
2) 注意 link 是这样的风格:
http://www.pse.pl/index.php?modul=21&id_rap=24&data=2017-07-19
。这里有趣的部分是 &data=2017-07-19
您可以构建一个循环,将具体日期传递到基数 link 的尾部,然后用 requests
打开每个这样的 link。解析更进一步。
我注意到的主要事情是,您发送到网站的 url 中的日期格式必须不同。日期元素(年、月和日)之间需要连字符。我还可以建议一种更简单的方式来度过每一天。
Arrows 是一个处理日期的模块。在这种情况下,我使用它来生成从 2015 年 1 月 1 日到 2015 年 1 月 3 日(含)的日期范围。
我也用它来格式化这些日期。
我使用 BeautifulSoup 找到表格,然后使用 pandas 将表格的内容提取到数据框中。最后,我将这些数据帧写入 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')