
Содержание статьи
Дэйв Грей
Web Scraping
Используя язык программирования Python, можно быстро и эффективно собирать данные из Интернета.
Веб-сбор определяется как:
инструмент для преобразования неструктурированных данных в Интернете в машиночитаемые структурированные данные, готовые для анализа. (источник)
Веб-сборка является ценным инструментом в наборе навыков специалиста по данным.
Теперь, что выскребть?

Общедоступные данные
Веб-сайт KanView поддерживает «Прозрачность в правительстве». Это также слоган сайта. Сайт предоставляет данные о заработной плате для штата Канзас. И это здорово!
Однако, как и многие государственные веб-сайты, он скрывает данные в подробных ссылках и таблицах. Для этого часто нужна «навигация по наилучшему предположению», чтобы найти конкретные данные, которые вы ищете. Я хотел использовать общедоступные данные Канзасских университетов в исследовательском проекте. Для начала мне нужно было собрать данные с помощью Python и сохранить их как JSON.
Ссылки JavaScript увеличивают сложность
Для достижения цели веб-скрапинг с помощью Python часто требует не больше, чем использование модуля Beautiful Soup. Beautiful Soup – это популярная библиотека Python, упрощающая реализацию веб-скрапинга путем обхода DOM (объектной модели документа).
Однако веб-сайт KanView использует ссылку JavaScript. Поэтому примеры с использованием Python и Beautiful Soup не будут работать без дополнительных дополнений.

Селен в помощь
Пакет Selenium используется для автоматизации взаимодействия веб-браузера с Python. С помощью Selenium можно программировать сценарий Python для автоматизации веб-браузера. После этого надоедливые ссылки JavaScript больше не являются проблемой.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import re
import pandas as pd
import os
Теперь Selenium приступит к сеансу браузера. Чтобы Selenium работал, он должен получить доступ к драйверу браузера. По умолчанию он будет искать в том же каталоге, что и сценарий Python. Ссылки на драйверы Chrome, Firefox, Edge и Safari доступны здесь. Нижеследующий пример кода использует Firefox:
#launch url
url = "
# create a new Firefox session
driver = webdriver.Firefox()
driver.implicitly_wait(30)
driver.get(url)
python_button = driver.find_element_by_id('MainContent_uxLevel1_Agencies_uxAgencyBtn_33') #FHSU
python_button.click() #click fhsu link
The python_button.click()
выше указывает Selenium нажать ссылку JavaScript на странице. Перейдя на страницу «Назови должностей», Selenium передает источник страницы компании «Beautiful Soup».

Переход к хорошему супу
Beautiful Soup остается лучшим способом просмотра DOM и сбора данных. После определения пустого списка и переменной счетчика пора попросить Beautiful Soup захватить все ссылки на странице, соответствующие регулярному выражению:
#Selenium hands the page source to Beautiful Soup
soup_level1=BeautifulSoup(driver.page_source, 'lxml')
datalist = [] #empty list
x = 0 #counter
for link in soup_level1.find_all('a', id=re.compile("^MainContent_uxLevel2_JobTitles_uxJobTitleBtn_")):
##code to execute in for loop goes here
Вы можете видеть на примере выше, что Beautiful Soup получит ссылку JavaScript для каждой должности в государственном агентстве. Теперь в блоке кода цикла for/in Selenium будет щелкать каждая ссылка JavaScript. Затем Beautiful Soup получит таблицу с каждой страницы.
#Beautiful Soup grabs all Job Title links
for link in soup_level1.find_all('a', id=re.compile("^MainContent_uxLevel2_JobTitles_uxJobTitleBtn_")):
#Selenium visits each Job Title page
python_button = driver.find_element_by_id('MainContent_uxLevel2_JobTitles_uxJobTitleBtn_' + str(x))
python_button.click() #click link
#Selenium hands of the source of the specific job page to Beautiful Soup
soup_level2=BeautifulSoup(driver.page_source, 'lxml')
#Beautiful Soup grabs the HTML table on the page
table = soup_level2.find_all('table')[0]
#Giving the HTML table to pandas to put in a dataframe object
df = pd.read_html(str(table),header=0)
#Store the dataframe in a list
datalist.append(df[0])
#Ask Selenium to click the back button
driver.execute_script("window.history.go(-1)")
#increment the counter variable before starting the loop over
x += 1

pandas: библиотека анализа данных Python
Beautiful Soup передает находки пандам. Панды используют его read_html
функция для чтения данных таблицы HTML в кадре данных. Фрейм данных добавляется в предварительно определенный пустой список.
Прежде чем блок кода цикла будет завершен, Selenium должен нажать кнопку «Назад» в браузере. Это означает, что следующая ссылка в цикле будет доступна для нажатия на странице списка вакансий.
После завершения цикла for/in Selenium посетил каждую ссылку на название должности. Beautiful Soup получил таблицу с каждой страницы. Pandas сохраняет данные из каждой таблицы в кадре данных. Каждый кадр данных является элементом списка данных. Отдельные кадры данных таблицы должны объединиться в один большой кадр данных. Затем данные будут преобразованы в формат JSON с помощью pandas.Dataframe.to_json:
#loop has completed
#end the Selenium browser session
driver.quit()
#combine all pandas dataframes in the list into one big dataframe
result = pd.concat([pd.DataFrame(datalist[i]) for i in range(len(datalist))],ignore_index=True)
#convert the pandas dataframe to JSON
json_records = result.to_json(orient="records")
Теперь Python создает файл данных JSON. Он готов к использованию!
#get current working directory
path = os.getcwd()
#open, write, and close the file
f = open(path + "\\fhsu_payroll_data.json","w") #FHSU
f.write(json_records)
f.close()
Автоматизированный процесс быстрый
Описанный выше автоматизированный процесс копирования веб-страниц завершается быстро. Selenium открывает окно обозревателя, которое вы видите, как работает. Это позволяет мне показать вам видео с экраном, которое показывает, насколько быстр процесс. Вы видите, как быстро скрипт переходит по ссылке, собирает данные, возвращается назад и щелкает следующую ссылку. Это делает получение данных из сотен ссылок на дело однозначных минут.
Полный код Python
Вот полный код Python. Я включил импорт для таблицы. Для этого требуется дополнительная строка кода, которая будет использовать таблицу для хорошей печати данных в вашем интерфейсе командной строки:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import re
import pandas as pd
from tabulate import tabulate
import os
#launch url
url = "
# create a new Firefox session
driver = webdriver.Firefox()
driver.implicitly_wait(30)
driver.get(url)
#After opening the url above, Selenium clicks the specific agency link
python_button = driver.find_element_by_id('MainContent_uxLevel1_Agencies_uxAgencyBtn_33') #FHSU
python_button.click() #click fhsu link
#Selenium hands the page source to Beautiful Soup
soup_level1=BeautifulSoup(driver.page_source, 'lxml')
datalist = [] #empty list
x = 0 #counter
#Beautiful Soup finds all Job Title links on the agency page and the loop begins
for link in soup_level1.find_all('a', id=re.compile("^MainContent_uxLevel2_JobTitles_uxJobTitleBtn_")):
#Selenium visits each Job Title page
python_button = driver.find_element_by_id('MainContent_uxLevel2_JobTitles_uxJobTitleBtn_' + str(x))
python_button.click() #click link
#Selenium hands of the source of the specific job page to Beautiful Soup
soup_level2=BeautifulSoup(driver.page_source, 'lxml')
#Beautiful Soup grabs the HTML table on the page
table = soup_level2.find_all('table')[0]
#Giving the HTML table to pandas to put in a dataframe object
df = pd.read_html(str(table),header=0)
#Store the dataframe in a list
datalist.append(df[0])
#Ask Selenium to click the back button
driver.execute_script("window.history.go(-1)")
#increment the counter variable before starting the loop over
x += 1
#end loop block
#loop has completed
#end the Selenium browser session
driver.quit()
#combine all pandas dataframes in the list into one big dataframe
result = pd.concat([pd.DataFrame(datalist[i]) for i in range(len(datalist))],ignore_index=True)
#convert the pandas dataframe to JSON
json_records = result.to_json(orient="records")
#pretty print to CLI with tabulate
#converts to an ascii table
print(tabulate(result, headers=["Employee Name","Job Title","Overtime Pay","Total Gross Pay"],tablefmt="psql"))
#get current working directory
path = os.getcwd()
#open, write, and close the file
f = open(path + "\\fhsu_payroll_data.json","w") #FHSU
f.write(json_records)
f.close()

Вывод
Веб-скреб с Python и Хороший суп является отличным инструментом для ваших навыков. Используйте веб-уборки, когда данные, с которыми вам нужно работать, общедоступны, но не обязательно удобны. Когда JavaScript предоставляет или «скрывает» содержимое, автоматизация браузера с помощью Селен гарантирует, что ваш код «видит» то, что вы (как пользователь) должны видеть. И, наконец, когда вы собираете таблицы, полные данных, панды это библиотека анализа данных Python, которая справится со всем этим.
Справка:
Следующая статья была полезной справкой для этого проекта:
https://pythonprogramminglanguage.com/web-scraping-with-pandas-and-beautifulsoup/
Свяжитесь со мной в любое время на LinkedIn или Twitter. И если вам понравилась эта статья, похлопайте по ней несколько раз. Я буду искренне признателен за это.
https://www.linkedin.com/in/davidagray/
Дэйв Грэй (@yesdavidgray) | Twitter
Последние твиты от Дэйва Грея (@yesdavidgray). Инструктор @FHSUInformatics * Разработчик * Музыкант * Предприниматель *…
twitter.com