Dr executed offenders html

Создание набора данных с помощью Python, парсинг веб-страниц

Я просмотрел много сообщений, но не нашел решения, которое вполне соответствует тому, что мне нужно. Во-первых, я предваряю, говоря, что я новичок в Python (я использую Python 2).

Я пытаюсь собрать данные с веб-страницы (http://www.tdcj.state .tx.us/death_row/dr_executed_offenders.html). Обратите внимание на красивую HTML-таблицу. Я смог прочитать это в список без особых проблем. Однако также обратите внимание на две колонки со ссылками. Я хотел бы удалить столбец первой ссылки (но я не знаю, как это сделать, поскольку мои данные находятся в списке).

Столбец второй ссылки немного сложнее. Я хочу заменить заголовок «Ссылка» на «Последнее заявление». Затем я хочу посетить каждую предоставленную ссылку, получить последний оператор и поместить его в соответствующую строку исходной таблицы, для которой я создал список.

Наконец, я хочу распечатать этот список в виде файла с разделителями табуляции, который можно прочитать в R как фрейм данных.

Это очень много для нуба. Скажите, правильно ли я подхожу к этой проблеме. Ниже приведен код, который у меня есть до сих пор. Мне не хватает кое-чего из того, что я хочу сделать, потому что я не знаю, с чего начать.

from bs4 import BeautifulSoup import requests from lxml import html import csv import string import sys #obtain the main url with bigger data main_url = "http://www.tdcj.state.tx.us/death_row/dr_executed_offenders.html" #convert the html to BeautifulSoup doc = requests.get(main_url) soup = BeautifulSoup(doc.text, 'lxml') #find in html the table tbl = soup.find("table", attrs = ) #create labels for list rows by table headers headings = [th.get_text() for th in tbl.find("tr").find_all("th")] #convert the unicode to string headers = [] for i in range(0,len(headings)-1): headers.append(str(headings[i])) #access the remaining information prisoners = [] for row in tbl.find_all("tr")[1:]: #attach the appropriate header to the appropriate corresponding data #also, converts unicode to string info = zip(headers, (str(td.get_text()) for td in row.find_all("td"))) #append each of the newly made rows prisoners.append(info) #print each row of the list to a file for R with open('output.txt', 'a') as output: for p in prisoners: output.write(str(p)+'\n') output.close() 

Если вы можете помочь мне разобраться с любой из трех частей, с которыми я борюсь, я был бы очень признателен!

Читайте также:  Python check if any is none

Источник

Как очистить таблицу и ее ссылки

И выберите год выполнения, введите ссылку на последний оператор и извлеките оператор . возможно, я бы создал 2 словаря, оба с номером выполнения в качестве ключа.

Впоследствии я бы классифицировал утверждения по длине, помимо » отметки » отказов в предоставлении или просто отказа.

Наконец, все будет скомпилировано в базе данных SQLite, и я бы отобразил график, показывающий, сколько сообщений, сгруппированных по типу, отправлялось каждый год.

Похоже, что Beautiful Soup — это путь, по которому нужно идти, у меня уже проблемы с печатью года казни . Конечно, я в конечном итоге не заинтересован в том, чтобы печатать годы казни, но это похоже на хороший способ проверка, правильно ли мой код размещает нужные мне теги.

tags = soup('td') for tag in tags: print(tag.get('href', None)) 

Почему предыдущий код выводит только None?

1 ответ

Используйте панд, чтобы достать стол и управлять им. Ссылки статичны, и я имею в виду, что их можно легко воссоздать, указав имя и фамилию преступника.

Затем вы можете использовать requests и BeautifulSoup , чтобы соскрести последнее заявление нарушителя, которое довольно трогательно.

import requests import pandas as pd def clean(first_and_last_name: list) -> str: name = "".join(first_and_last_name).replace(" ", "").lower() return name.replace(", Jr.", "").replace(", Sr.", "").replace("'", "") base_url = "https://www.tdcj.texas.gov/death_row" response = requests.get(f"/dr_executed_offenders.html") df = pd.read_html(response.text, flavor="bs4") df = pd.concat(df) df.rename(columns=, inplace=True) df["Offender Information"] = df[ ["Last Name", 'First Name'] ].apply(lambda x: f"/dr_info/.html", axis=1) df["Last Statement URL"] = df[ ["Last Name", 'First Name'] ].apply(lambda x: f"/dr_info/last.html", axis=1) df.to_csv("offenders.csv", index=False) 

enter image description here

На самом деле я пошел дальше и добавил код, который извлекает последние утверждения всех нарушителей.

import random import time import pandas as pd import requests from lxml import html base_url = "https://www.tdcj.texas.gov/death_row" response = requests.get(f"/dr_executed_offenders.html") statement_xpath = '//*[@id="content_right"]/p[6]/text()' def clean(first_and_last_name: list) -> str: name = "".join(first_and_last_name).replace(" ", "").lower() return name.replace(", Jr.", "").replace(", Sr.", "").replace("'", "") def get_last_statement(statement_url: str) -> str: page = requests.get(statement_url).text statement = html.fromstring(page).xpath(statement_xpath) text = next(iter(statement), "") return " ".join(text.split()) df = pd.read_html(response.text, flavor="bs4") df = pd.concat(df) df.rename( columns=, inplace=True, ) df["Offender Information"] = df[ ["Last Name", 'First Name'] ].apply(lambda x: f"/dr_info/.html", axis=1) df["Last Statement URL"] = df[ ["Last Name", 'First Name'] ].apply(lambda x: f"/dr_info/last.html", axis=1) offender_data = list( zip( df["First Name"], df["Last Name"], df["Last Statement URL"], ) ) statements = [] for item in offender_data: *names, url = item print(f"Fetching statement for . ") statements.append(get_last_statement(statement_url=url)) time.sleep(random.randint(1, 4)) df["Last Statement"] = statements df.to_csv("offenders_data.csv", index=False) 

Это займет пару минут, потому что код «спит» где-то между 1 и 4 секундами, более или менее, так что сервер не будет злоупотреблять.

Читайте также:  Can abstract class have constructor java

Как только это будет сделано, вы получите файл .csv с данными всех преступников и их заявлениями, если таковые были.

Источник

Как выполнить итерацию до конца, используя Selenium

Я пытаюсь экспортировать таблицу данных с https://www.tdcj.texas.gov/ death_row/dr_executed_offenders.html на Python с помощью Selenium (в конечном итоге я хочу скопировать данные в файл csv с помощью Python). Я застрял на первой строке — он повторяется до 7-го столбца, а не до 10-го, который является последним один.

browser = webdriver.Chrome() action = ActionChains(browser) browser.get('https://www.tdcj.texas.gov/death_row/dr_executed_offenders.html') list = [] rows = browser.find_elements_by_xpath('//th[@style="text-align: center" and(@scope="col")]') for i in range(1,len(rows)+1): row = browser.find_element_by_css_selector ('#content_right > div.overflow > table > tbody > tr:nth-child(1) > th:nth-child('+str(i)+')' ) action.move_to_element (row).perform () row = browser.find_element_by_css_selector ('#content_right > div.overflow > table > tbody > tr:nth-child(1) > th:nth-child('+str(i)+')' ) content = row.text list.append(content) print(list) 
['Execution', 'Link', 'Link', 'Last Name', 'First Name', 'TDCJ\nNumber', 'Age'] 

А как насчет даты, расы и страны? Не могу найти где проблема.

1 ответ

Чтобы извлечь заголовки столбцов с веб-сайта, вы можете использовать понимание списка, и вы можете использовать любой из следующих стратегии поиска:

driver.get('https://www.tdcj.texas.gov/death_row/dr_executed_offenders.html') print([my_elem.text for my_elem in driver.find_elements(By.CSS_SELECTOR, "table[title='Table showing list of executed inmates']>tbody>tr th")]) driver.quit() 
driver.get('https://www.tdcj.texas.gov/death_row/dr_executed_offenders.html') print([my_elem.text for my_elem in driver.find_elements(By.XPATH, "//table[@title='Table showing list of executed inmates']/tbody/tr//th")]) driver.quit() 
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC 
['Execution', 'Link', 'Link', 'Last Name', 'First Name', 'TDCJ\nNumber', 'Age', 'Date', 'Race', 'County'] 

Источник

Оцените статью