Как использовать метод pd.DataFrame для ручного создания кадра данных из информации, очищенной с помощью Beautifulsoup4 - PullRequest
1 голос
/ 19 июня 2019

Я добрался до того момента, когда все tr данные были очищены, и я смог получить отличную распечатку. Но когда я иду к реализации pd.DataFrame, как в df= pd.DataFrame({"A": a}) и т. Д., Я получаю синтаксическую ошибку

Вот список моих импортированных библиотек в блокноте Jupyter:

import pandas as pd
import numpy as np
import bs4 as bs
import requests
import urllib.request
import csv
import html5lib
from pandas.io.html import read_html
import re

Вот мой код:

source = urllib.request.urlopen('https://www.zipcodestogo.com/Texas/').read()
soup = bs.BeautifulSoup(source,'html.parser')

table_rows = soup.find_all('tr')
table_rows

for tr in table_rows:
    td = tr.find_all('td')
    row = [i.text for i in td]
    print(row)

texas_info = pd.DataFrame({
        "title": Texas 
        "Zip Code" : [Zip Code], 
        "City" :[City],
})

texas_info.head()

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

Ответы [ 2 ]

0 голосов
/ 19 июня 2019

Если вы хотите создать вручную, с помощью bs4 4.7.1 вы можете использовать псевдоклассы :not, :contains и :nth-of-type, чтобы изолировать два интересующих столбца, затем создать dict, а затем преобразовать в df

import pandas as pd
import urllib
from bs4 import BeautifulSoup as bs

source = urllib.request.urlopen('https://www.zipcodestogo.com/Texas/').read()
soup = bs(source,'lxml')
zips = [item.text for item in soup.select('.inner_table:contains(Texas) td:nth-of-type(1):not([colspan])')]
cities =  [item.text for item in soup.select('.inner_table:contains(Texas) td:nth-of-type(2):not([colspan])')]
d = {'Zips': zips,'Cities': cities}
df = pd.DataFrame(d)
df = df[1:].reset_index(drop = True)

Вы можете объединить селекторы в одну строку:

import pandas as pd
import urllib
from bs4 import BeautifulSoup as bs

source = urllib.request.urlopen('https://www.zipcodestogo.com/Texas/').read()
soup = bs(source,'lxml')
items = [item.text for item in soup.select('.inner_table:contains(Texas) td:nth-of-type(1):not([colspan]), .inner_table:contains(Texas) td:nth-of-type(2):not([colspan])')]
d = {'Zips': items[0::2],'Cities': items[1::2]}
df = pd.DataFrame(d)
df = df[1:].reset_index(drop = True)
print(df)

Замечу, что вы хотите создать вручную, но для будущих читателей стоит знать, что вы можете просто использовать pandas read_html

import pandas as pd

table = pd.read_html('https://www.zipcodestogo.com/Texas/')[1]
table.columns = table.iloc[1]
table = table[2:]
table = table.drop(['Zip Code Map', 'County'], axis=1).reset_index(drop=True)
print(table)
0 голосов
/ 19 июня 2019

Попробуйте создать DataFrame и выполните цикл for, чтобы добавить каждую строку таблицы в DataFrame.

    df = pd.DataFrame()
    for tr in table_rows:
        td = tr.find_all('td')
        row = [i.text for i in td]
        print(row)
        zipCode = row[0] # assuming first column
        city = row[1] # assuming second column

        df = df.append({"Zip Code": zipCode, "City" : city}, ignore_index=True)

Если вам нужны только эти два столбца, вы не должны включать title в DataFrame (который создаст другой столбец); в этой строке также произошла синтаксическая ошибка из-за пропущенной запятой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...