Мало что с кодом:
Код, который у вас есть, на самом деле ничего не делает. На самом деле, если вы попытаетесь запустить это, вы должны получить тонны ошибок. Там нет никакого способа увидеть этот результат просто зацикливание тех же значений с тем, что вы предоставили.
Отступ отключен,
вы ссылаетесь на переменную source
, которая не была определена. Вы ссылаетесь на переменную cols
, которая также не определена.
Вы инициализируете фрейм данных 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)