Мне нужна помощь по двум основным причинам: (1) очистка веб-страницы и (2) преобразование очищенных данных в pandas фрейм данных (в основном, чтобы я мог выводить как .csv, но просто создав pandas df пока достаточно). Вот что я сделал для обоих:
(1) Очистка веб-сайта:
- Я пытаюсь очистить эту страницу: https://www.osha.gov/pls/imis/establishment.inspection_detail?id=1285328.015&id=1284178.015&id=1283809.015&id=1283549.015&id=1282631.015. Моя конечная цель - создать фрейм данных, который в идеале содержал бы только ту информацию, которую я ищу (т.е. я мог бы выбрать только те части сайта, которые мне интересны для моего df); все в порядке, если мне нужно получить все данных на данный момент.
- Как видно из URL-адреса, а также гиперссылок идентификатора под «Краткой ссылкой» в верхней части страницы, на этой странице имеется пять отдельных записей. Мне бы хотелось, чтобы каждый из этих идентификаторов / записей рассматривался как отдельная строка в моем pandas df.
EDIT : Благодаря полезному комментарию я включаю пример того, что я в конечном итоге хотел бы в таблице ниже. Первая строка представляет заголовки / имена столбцов, а вторая строка представляет первую проверку.
inspection_id open_date inspection_type close_conference close_case violations_serious_initial
1285328.015 12/28/2017 referral 12/28/2017 06/21/2018 2
В основном полагаясь на BeautifulSoup4, я пробовал несколько разных способов получить интересующие меня элементы страницы:
# This is meant to give you the first instance of Case Status, which in the case of this page is "CLOSED".
case_status_template = html_soup.head.find('div', {"id" : "maincontain"},
class_ = "container").div.find('table', class_ = "table-bordered").find('strong').text
# I wasn't able to get the remaining Case Statuses with find_next_sibling or find_all, so I used a different method:
for table in html_soup.find_all('table', class_= "table-bordered"):
print(table.text)
# This gave me the output I needed (i.e. the Case Status for all five records on the page),
# but didn't give me the structure I wanted and didn't really allow me to connect to the other data on the page.
# I was also able to get to the same place with another page element, Inspection Details.
# This is the information reflected on the page after "Inspection: ", directly below Case Status.
insp_details_template = html_soup.head.find('div', {"id" : "maincontain"},
class_ = "container").div.find('table', class_ = "table-unbordered")
for div in html_soup.find_all('table', class_ = "table-unbordered"):
print(div.text)
# Unfortunately, although I could get these two pieces of information to print,
# I realized I would have a hard time getting the rest of the information for each record.
# I also knew that it would be hard to connect/roll all of these up at the record level.
Итак, я попытался немного по-другому подходить. Сосредоточившись вместо этого на версии этой страницы с одной проверочной записью, я подумал, что, может быть, я мог бы просто взломать ее, используя этот фрагмент кода:
url = 'https://www.osha.gov/pls/imis/establishment.inspection_detail?id=1285328.015'
response = get(url)
html_soup = BeautifulSoup(response.text, 'html.parser')
first_table = html_soup.find('table', class_ = "table-borderedu")
first_table_rows = first_table.find_all('tr')
for tr in first_table_rows:
td = tr.find_all('td')
row = [i.text for i in td]
print(row)
# Then, actually using pandas to get the data into a df and out as a .csv.
dfs_osha = pd.read_html('https://www.osha.gov/pls/imis/establishment.inspection_detail?id=1285328.015',header=1)
for df in dfs_osha:
print(df)
path = r'~\foo'
dfs_osha = pd.read_html('https://www.osha.gov/pls/imis/establishment.inspection_detail?id=1285328.015',header=1)
for df[1,3] in dfs_osha:
df.to_csv(os.path.join(path,r'osha_output_table1_012320.csv'))
# This worked better, but didn't actually give me all of the data on the page,
# and wouldn't be replicable for the other four inspection records I'm interested in.
Итак, наконец, я нашел здесь довольно удобный пример : https://levelup.gitconnected.com/quick-web-scraping-with-python-beautiful-soup-4dde18468f1f. Я пытался пройти через это, и дошел до того, что придумал этот код:
for elem in all_content_raw_lxml:
wrappers = elem.find_all('div', class_ = "row-fluid")
for x in wrappers:
case_status = x.find('div', class_ = "text-center")
print(case_status)
insp_details = x.find('div', class_ = "table-responsive")
for tr in insp_details:
td = tr.find_all('td')
td_row = [i.text for i in td]
print(td_row)
violation_items = insp_details.find_next_sibling('div', class_ = "table-responsive")
for tr in violation_items:
tr = tr.find_all('tr')
tr_row = [i.text for i in tr]
print(tr_row)
print('---------------')
К сожалению, я столкнулся с слишком многими ошибками, чтобы иметь возможность использовать его, поэтому я был вынужден отказаться от проекта, пока я не получу дальнейшие указания. Надеюсь, что код, которым я поделился до сих пор, по крайней мере, показывает усилия, которые я вложил, даже если это не так уж много для достижения окончательного результата! Спасибо.