我已经设法公开了正确的数据(其中一些数据是在页面中动态计算的,所以比我想象的要复杂一些),但现在我需要将其放入JSON字符串中,尽管尝试了很多次,我还是卡住了!
Python脚本如下所示(使用Selenium和BeautifulSoup):
from bs4 import BeautifulSoup
from selenium import webdriver
import datetime
from dateutil import parser
import requests
import json
url = 'https://www.braintree.gov.uk/bins-waste-recycling/route-3-collection-dates/1'
browser = webdriver.Chrome(executable_path = r'C:/Users/user/Downloads/chromedriver.exe')
browser.get(url)
html = browser.execute_script("return document.getElementsByTagName('html')[0].innerHTML")
soup = BeautifulSoup(html, "html.parser")
data=soup.find_all("div", {"class":"date_display"})
#print(data)
#out = {}
for data in data:
bin_colour = data.find('h3').text
bin_date = parser.parse(data.find('p').text).strftime('%Y-%m-%d')
print(bin_colour)
print(bin_date)
print()
browser.quit()这将导致:
Grey Bin
2021-06-30
Green Bin
2021-06-23
Clear Sack
2021-06-23
Food Bin
2021-06-23这可能(可能)不是最好的代码/方法,所以我对您的建议持开放态度。我们的主要目标是:
{"Grey Bin": "2021-06-30", "Green Bin": "2021-06-23", "Clear Sack": "2021-06-23", "Food Bin": "2021-06-23"}希望这是有意义的,我已经尝试了各种方法将数据转换为正确的格式,但似乎在尝试了很多小时后都失去了一切,希望你们能提供帮助。
更新:MendelG的两个解决方案都工作得很好。Vitalis的解决方案提供了四个输出,最后一个是所需的输出-所以感谢你们提供了非常快速和有效的解决方案-我接近了,但看不到树的木头!
发布于 2021-06-19 00:20:30
要获取字典格式的数据,您可以尝试:
out = {}
for data in tag:
out[data.find("h3").text] = parser.parse(data.find("p").text).strftime("%Y-%m-%d")
print(out)或者,使用字典理解:
print(
{
data.find("h3").text: parser.parse(data.find("p").text).strftime("%Y-%m-%d")
for data in tag
}
)输出:
{'Grey Bin': '2021-06-30', 'Green Bin': '2021-06-23', 'Clear Sack': '2021-06-23', 'Food Bin': '2021-06-23'}发布于 2021-06-19 00:27:22
您可以创建一个空字典,在其中添加值并打印它。
解决方案
from bs4 import BeautifulSoup
from selenium import webdriver
import datetime
from dateutil import parser
import requests
import json
url = 'https://www.braintree.gov.uk/bins-waste-recycling/route-3-collection-dates/1'
browser = webdriver.Chrome(executable_path='/snap/bin/chromium.chromedriver')
browser.get(url)
html = browser.execute_script("return document.getElementsByTagName('html')[0].innerHTML")
soup = BeautifulSoup(html, "html.parser")
data = soup.find_all("div", {"class":"date_display"})
result = {}
for item in data:
bin_colour = item.find('h3').text
bin_date = parser.parse(item.find('p').text).strftime('%Y-%m-%d')
result[bin_colour]=bin_date
print(result)输出
{'Grey Bin': '2021-06-30', 'Green Bin': '2021-06-23', 'Clear Sack': '2021-06-23', 'Food Bin': '2021-06-23'}如果需要list格式的输出,也可以采用类似的方法,但需要对值进行.append操作,就像我在这里使用Trouble retrieving elements and looping pages using next page button一样
如果需要双引号,请使用下面的打印命令:
print(json.dumps(result))它将打印:
{"Grey Bin": "2021-06-30", "Green Bin": "2021-06-23", "Clear Sack": "2021-06-23", "Food Bin": "2021-06-23"}发布于 2021-06-19 01:33:40
您可以使用requests和re收集所有列出的日期。您可以对包含每种集合类型日期的各种JavaScript对象进行正则表达式。然后,您需要将每个月的值加1,才能得到1-12范围内的月份;这可以通过regex命名组来完成。可以将这些日期转换为实际日期,以便以后进行筛选。
最初将所有日期存储在字典中,集合类型为key,收集日期列表为values,您可以使用zip_longest创建一个DataFrame。然后,您可以使用筛选来查找给定集合的下一个集合日期。
我使用了几个助手函数来实现这一点。
import requests
from dateutil import parser
from datetime import datetime
from pandas import to_datetime, DataFrame
from itertools import zip_longest
def get_dates(dates):
dates = [re.sub(r'(?P<g1>\d+),(?P<g2>\d+),(?P<g3>\d+)$', lambda d: parser.parse('-'.join([d.group('g1'), str(int(d.group('g2')) + 1), d.group('g3')])).strftime('%Y-%m-%d'), i)
for i in re.findall(r'Date\((\d{4},\d{1,2},\d{1,2}),', dates)]
dates = [datetime.strptime(i, '%Y-%m-%d').date() for i in dates]
return dates
def get_next_collection(collection, df):
return df[df[collection] >= to_datetime('today')][collection].iloc[0]
collection_types = ['grey', 'green', 'clear', 'food']
r = requests.get('https://www.braintree.gov.uk/bins-waste-recycling/route-3-collection-dates/1')
collections = {}
for collection in collection_types:
dates = re.search(r'var {0}(?:(?:bin)|(?:sack)) = (\[.*?\])'.format(collection), r.text, re.S).group(1)
collections[collection] = get_dates(dates)
df = DataFrame(zip_longest(collections['grey'], collections['green'],
collections['clear'], collections['food']),
columns = collection_types)
get_next_collection('grey', df)您还可以使用生成器和@Martijn Pieters 详细介绍的islice来直接处理字典条目(保存收集日期),并限制您感兴趣的未来日期,例如
filtered = (i for i in collections['grey'] if i >= date.today())
list(islice(filtered, 3))修改后的导入行包括:
from itertools import zip_longest, islice
from datetime import datetime, date这样您就不需要导入pandas或创建DataFrame了。
https://stackoverflow.com/questions/68038019
复制相似问题