доступ к вложенному столбцу другого столбца из таблицы википедии с помощью Beautifulsoup - PullRequest
0 голосов
/ 31 января 2019

У меня есть проект, который требует от нас скачать и прочитать таблицу из Википедии и использовать эту информацию для расчета.страница википедии - https://en.wikipedia.org/wiki/List_of_United_States_cities_by_crime_rate#Criticism_of_ranking_crime_data

требуется, чтобы мы принимали общее насильственное преступление каждого города, перечисленные штаты (штаты повторяются), однако все ячейки для этих столбцов имеют только тег.это под одной таблицей, вопрос в том, как бы я использовал Beautifulsoup, чтобы прочитать этот конкретный столбец, который находится под столбцом «Насильственное преступление»

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

state = soup.find_all('th', limit = 7)
for row in state:
    row_data = row.get_text(strip = True, separator = '|').split('|')[0:1]
    outfile.write(str(row_data)+ "\n")
umber = soup.find_all('td')

for column in number:
     column_data = column.get_text(strip = True, separator = '|').split('|')[0:1]

     outfile.write(str(column_data)+ "\n")

Я в основном хочу сохранить эту информацию в виде списка для последующего использования, а затем использовать ссылки на каждый город идостаньте их шнуры, а затем отошлите их в несколько городов Техаса для ближайшего к границе

Нам разрешено использовать только BeautifulSoup и CSV без Pandas или NumPy

Редактировать: только функции Write outдля тестирования, а также.Это только для того, чтобы увидеть, правильно ли он получает информацию из таблицы.Моя консоль IDE не может отобразить все из них, так что написать это было следующей лучшей вещью, о которой я мог подумать

1 Ответ

0 голосов
/ 31 января 2019

Похоже, это просто вопрос создания ваших списков.Вы можете сделать это, инициализировав свой список, а затем добавив к нему свой список.Или вы можете добавить к нему каждый из элементов вашего цикла for.Или вы можете сделать это более кратким, выполнив понимание списка.

Причина, по которой вы ничего не получаете, состоит в том, что вы продолжаете перезаписывать свои row_data и column_data в цикле.И он будет записывать в файл, однако он будет ставить новую строку после каждого, когда я предполагаю, что вы захотите написать всю строку, а затем сделать новую строку, поэтому я бы также поместил вашу записьпосле создания / завершения списка:

Объединение списка в список:

row_data = []
for row in state:
    row_data = row_data + row.get_text(strip = True, separator = '|').split('|')[0:1]
outfile.write(str(row_data)+ "\n")


number = soup.find_all('td')

column_data = []
for column in number:
     column_data = column_data + column.get_text(strip = True, separator = '|').split('|')[0:1]
outfile.write(str(column_data)+ "\n")

Добавление элемента / элемента в список:

# Initiate and then append to a list
row_data = []
for row in state:
    row_data.append(row.text)
outfile.write(str(row_data)+ "\n")


number = soup.find_all('td')
column_data = []
for column in number:
     column_data.append(column.text)
outfile.write(str(column_data)+ "\n")

Понимание списка:

#List comprehension
row_data = [ row.text for row in state ]
outfile.write(str(row_data)+ "\n")

column_data = [ column.text for column in number ] 
outfile.write(str(column_data)+ "\n")

Что касается получения этих подколонок, то это сложно, потому что это не дочерние теги.Однако они являются следующим тегом <tr> после тега <<code>th>, который вы извлекаете, поэтому мы можем использовать его.

import bs4
import requests
import csv



url = 'https://en.wikipedia.org/wiki/List_of_United_States_cities_by_crime_rate#Criticism_of_ranking_crime_data'

response = requests.get(url)

soup = bs4.BeautifulSoup(response.text, 'html.parser')

# Only want State and City so limit = 2
headers = soup.find_all('th', limit = 2)
sub_headers = headers[0].findNext('tr')


# Initiate and then append to a list
header_data = []
for data in headers:
    header_data.append(data.text.strip())


sub_header_data = []
for data in sub_headers.find_all('th'):
    sub_header_data.append(data.text.strip())

# Only want to append the first Total column from the sub_headers    
header_data.append(sub_header_data[0])


with open('C:/test.csv', mode='w', newline='') as outfile:
    writer = csv.writer(outfile)
    writer.writerow(header_data)



    table_body = soup.find_all('tbody')[1]
    rows = table_body.find_all('tr')
    for row in rows:
        tds = row.find_all('td', limit = 4)

        #Skip the blank rows of data
        if tds == []:
            continue

        tds_data = []
        for data in tds:
            tds_data.append(data.text.strip())

        #Remove the Population number/data
        del tds_data[2]

        writer.writerow(tds_data)
...