BeautifulSoup от таблицы до датафрейма - PullRequest
0 голосов
/ 23 января 2019

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

pop_source = requests.get("http://zipatlas.com/us/tx/austin/zip-code-comparison/population-density.htm").text

soup = BeautifulSoup(pop_source, 'html5lib')    
source = soup.find_all('td',class_ = 'report_data')


pop = pd.DataFrame(columns=['Zip Code','Population'])


row_data = [data.text for data in source]

temp_df = pd.DataFrame([row_data], columns=['#','Zip Code','Location','City', 'Population','People/Sq.Mile','National Rank'])   

temp_df = temp_df[['Zip Code','Population']]   
pop = pop.append(temp_df).reset_index(drop=True)    
pop

1 Ответ

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

Мало что с кодом:

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

  2. Отступ отключен,

  3. вы ссылаетесь на переменную source, которая не была определена. Вы ссылаетесь на переменную cols, которая также не определена.

  4. Вы инициализируете фрейм данных pop с двумя столбцами и пытаетесь добавить фрейм данных с 7 столбцами.

Здесь происходят всевозможные проблемы.

Рассматривали ли вы просто использование прямых панд для формирования кадра данных? Вы все еще можете использовать BeautifulSoup, но pandas может сделать всю работу за вас, и кажется, что вам нужно немного больше практиковаться в переборе элементов с BeautifulSoup (на самом деле вы даже никогда не использовали .find или .find_all для поиска тегов связано с таблицей, которую вы хотите.)

Если вам нужен способ BeautifulSoup, просто дайте мне знать, и я тоже могу предложить этот способ, но, честно говоря, это намного больше, чем просто использовать .read_html() с пандами здесь.

import pandas as pd

url = 'http://zipatlas.com/us/tx/austin/zip-code-comparison/population-density.htm'

tables = pd.read_html(url)

df = tables[11][1:]
df.columns = tables[11].iloc[0]

Выход:

print (df)
0     # Zip Code      ...      People / Sq. Mile National Rank
1    1.    78705      ...               11008.66          #519
2    2.    78751      ...                5822.28        #1,374
3    3.    78752      ...                5435.92        #1,528
4    4.    78741      ...                5346.47        #1,562
5    5.    78723      ...                5175.95        #1,640
6    6.    78704      ...                5001.96        #1,713
7    7.    78758      ...                4954.80        #1,730
8    8.    78702      ...                4501.98        #2,015
9    9.    78757      ...                4380.92        #2,087
10  10.    78756      ...                4298.80        #2,139
11  11.    78745      ...                4063.22        #2,295
12  12.    78753      ...                3973.96        #2,350
13  13.    78703      ...                3491.54        #2,753
14  14.    78731      ...                3031.63        #3,167
15  15.    78759      ...                2998.68        #3,199
16  16.    78727      ...                2856.67        #3,371
17  17.    78749      ...                2795.02        #3,438
18  18.    78728      ...                2640.31        #3,614
19  19.    78721      ...                2568.43        #3,690
20  20.    78722      ...                2567.53        #3,692
21  21.    78729      ...                2366.94        #3,944
22  22.    78701      ...                2326.65        #3,995
23  23.    78748      ...                1961.73        #4,504
24  24.    78750      ...                1731.01        #4,870
25  25.    78744      ...                1464.78        #5,311
26  26.    78746      ...                1152.39        #5,971
27  27.    78717      ...                1081.05        #6,119
28  28.    78739      ...                 768.80        #7,006
29  29.    78734      ...                 698.96        #7,267
30  30.    78724      ...                 555.85        #7,870
31  31.    78726      ...                 543.24        #7,940
32  32.    78733      ...                 510.92        #8,116
33  33.    78754      ...                 484.73        #8,255
34  34.    78735      ...                 474.14        #8,318
35  35.    78732      ...                 416.13        #8,702
36  36.    78742      ...                 321.40        #9,467
37  37.    78730      ...                 257.86       #10,189
38  38.    78738      ...                 213.29       #10,829
39  39.    78747      ...                 194.02       #11,173
40  40.    78736      ...                 187.88       #11,301
41  41.    78737      ...                 143.90       #12,372
42  42.    78725      ...                 116.87       #13,282
43  43.    78719      ...                  93.88       #14,377

[43 rows x 7 columns]

с BeautifulSoup

Это не идеальный способ сделать это. Хотя этот сайт довольно прост с тегами table, tr, td. Что вам, вероятно, понадобится, - это сначала захватить все строки, а затем пройтись по каждой строке, чтобы получить теги <td>. Но вы схватили все теги <td> одним махом. Что все еще нормально, но нам нужно разбить это на каждый ряд.

Все, что я сделал, - это разбил это на группы по 7, так как это количество столбцов. Обратите внимание, я делаю огромное предположение, что все данные есть. Если это не так, то таблица будет отключена или строки, столбцы будут смещены.

import requests
import pandas as pd
import bs4


# Create a function called "chunks" with two arguments, l and n:
def chunks(l, n):
    # For item i in a range that is a length of l,
    for i in range(0, len(l), n):
        # Create an index range for l of n items:
        yield l[i:i+n]



pop_source = requests.get("http://zipatlas.com/us/tx/austin/zip-code-comparison/population-density.htm").text

soup = bs4.BeautifulSoup(pop_source, 'html5lib')


source = soup.find_all('td',class_ = 'report_data')

pop = pd.DataFrame(columns=['#','Zip Code','Location','City', 'Population','People/Sq.Mile','National Rank'])

row_data = [data.text for data in source]

rows_data = list(chunks(row_data, 7))

for ele in rows_data:
    temp_df = pd.DataFrame([ele], columns=['#','Zip Code','Location','City', 'Population','People/Sq.Mile','National Rank'])
    pop = pop.append(temp_df).reset_index(drop=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...