अजगर सुंदरसिंग टेबल


90

मैं अजगर requestsऔर ब्यूटीफुल सीख रहा हूं । एक अभ्यास के लिए, मैंने एक त्वरित एनवाईसी पार्किंग टिकट पार्सर लिखने के लिए चुना है। मैं एक html प्रतिक्रिया प्राप्त करने में सक्षम हूं जो काफी बदसूरत है। मुझे lineItemsTableसभी टिकटों को हथियाने और पार्स करने की जरूरत है ।

आप यहां जाकर पृष्ठ को पुन: प्रस्तुत कर सकते हैं: https://paydirect.link2gov.com/NYCParking-Plate/ItemSearchऔर एक NYप्लेट डालकरT630134C

soup = BeautifulSoup(plateRequest.text)
#print(soup.prettify())
#print soup.find_all('tr')

table = soup.find("table", { "class" : "lineItemsTable" })
for row in table.findAll("tr"):
    cells = row.findAll("td")
    print cells

क्या कोई व्यक्ति कृपा करके मेरी सहायता करेगा? सभी के लिए सरल trमुझे कहीं भी नहीं मिलता है।


करीब से पढ़े जाने पर, मुझे वास्तव में यकीन नहीं है कि आपका प्रश्न क्या है। क्या आप स्पष्ट कर सकते हैं कि आपको किस हिस्से की मदद चाहिए?
टीएमएल

प्रश्न लिंक-टूटी हुई: सामान्य <तालिका> के लिए कार्यशील उदाहरण को बंद करें।
यूसोब्रैसिलेरो

जवाबों:


174

हेयर यू गो:

data = []
table = soup.find('table', attrs={'class':'lineItemsTable'})
table_body = table.find('tbody')

rows = table_body.find_all('tr')
for row in rows:
    cols = row.find_all('td')
    cols = [ele.text.strip() for ele in cols]
    data.append([ele for ele in cols if ele]) # Get rid of empty values

यह आपको देता है:

[ [u'1359711259', u'SRF', u'08/05/2013', u'5310 4 AVE', u'K', u'19', u'125.00', u'$'], 
  [u'7086775850', u'PAS', u'12/14/2013', u'3908 6th Ave', u'K', u'40', u'125.00', u'$'], 
  [u'7355010165', u'OMT', u'12/14/2013', u'3908 6th Ave', u'K', u'40', u'145.00', u'$'], 
  [u'4002488755', u'OMT', u'02/12/2014', u'NB 1ST AVE @ E 23RD ST', u'5', u'115.00', u'$'], 
  [u'7913806837', u'OMT', u'03/03/2014', u'5015 4th Ave', u'K', u'46', u'115.00', u'$'], 
  [u'5080015366', u'OMT', u'03/10/2014', u'EB 65TH ST @ 16TH AV E', u'7', u'50.00', u'$'], 
  [u'7208770670', u'OMT', u'04/08/2014', u'333 15th St', u'K', u'70', u'65.00', u'$'], 
  [u'$0.00\n\n\nPayment Amount:']
]

ध्यान देने योग्य बातें:

  • उपरोक्त आउटपुट में अंतिम पंक्ति, भुगतान राशि तालिका का हिस्सा नहीं है, लेकिन यह है कि तालिका कैसे रखी गई है। यदि सूची की लंबाई 7 से कम है, तो आप इसे जांच कर फ़िल्टर कर सकते हैं।
  • हर पंक्ति के अंतिम कॉलम को अलग से हैंडल करना होगा क्योंकि यह एक इनपुट टेक्स्ट बॉक्स है।

6
मुझे आश्चर्य है कि यह आपके लिए क्यों काम करता है ... मुझे मिलता हैrows = table_body.find_all('tr') AttributeError: 'NoneType' object has no attribute 'find_all'
Cmag

@Cag आप सुंदर सूप 4 का उपयोग कर रहे हैं?
शक्तिमा

1
के find_allसाथ बदलेंfindAll
user2314737

4
@ user2314737 बीएस ऊंट मामले और अंडरस्कोर नोटेशन दोनों का समर्थन करता है। मैं अंडरस्कोर का उपयोग करता हूं जो पायथन कोडिंग दिशानिर्देशों के अनुरूप है।
शकुतिमान

3
ठीक है मैंने अपनी त्रुटि का समाधान किया: html के निरीक्षण दृश्य में यह tbody दिखाता है, हालांकि, जब मैंने इसका मूल्य छापा तो table = soup.find('table', attrs={'class':'analysis'})इसमें कोई tbody नहीं दिखा, इसलिए बस td और tr को खोजने का काम किया। इसलिए मेरे अनुसार त्रुटि होने का कारण AttributeError: 'NoneType' object has no attribute 'find_all'तब होता है जब हम एक टैग या फील्ड पास करते हैं जो पेज के HTML में नहीं होता है।
उमेश कौशिक

23

हल, यह है कि कैसे अपने पार्स अपने HTML परिणाम:

table = soup.find("table", { "class" : "lineItemsTable" })
for row in table.findAll("tr"):
    cells = row.findAll("td")
    if len(cells) == 9:
        summons = cells[1].find(text=True)
        plateType = cells[2].find(text=True)
        vDate = cells[3].find(text=True)
        location = cells[4].find(text=True)
        borough = cells[5].find(text=True)
        vCode = cells[6].find(text=True)
        amount = cells[7].find(text=True)
        print amount

18

अद्यतन उत्तर

यदि किसी प्रोग्रामर को वेबपेज से केवल पार्सिंग टेबल में रुचि है, तो वे पांडा विधि का उपयोग कर सकते हैं pandas.read_html

मान लें कि हम वेबसाइट से जीडीपी डेटा तालिका निकालना चाहते हैं: https://worldpopulationreview.com/countries/countries-by-gdp/#worldCountries

फिर निम्नलिखित कोड पूरी तरह से काम करता है (सुंदरसो और फैंसी html की कोई आवश्यकता नहीं):

import pandas as pd
import requests

url = "https://worldpopulationreview.com/countries/countries-by-gdp/#worldCountries"

r = requests.get(url)
df_list = pd.read_html(r.text) # this parses all the tables in webpages to a list
df = df_list[0]
df.head()

उत्पादन

वेबसाइट से तालिका की पहली पाँच पंक्तियाँ


सहमत - यह स्पष्ट रूप से 2020 तक का सबसे अच्छा तरीका है!
kfmfe04

2
यदि आप पहले से ही अपनी परियोजना में कहीं पंडों का उपयोग करते हैं। एक तालिका के लिए बहुत अधिक निर्भरताएँ
Сергей oneхницкий

हाहा आपने मेरे परीक्षित बोले की नकल की और उत्तर में सुधार किया। खैर, कम से कम मुझे यह जानकर अच्छा लगा कि पांडा के पास ऐसा तरीका है। अच्छा!
यूसरोबैसिलिरो

हाँ, मैं आपके उदाहरण से जीडीपी के डेटा का उपयोग करता था। हाँ, यदि आप त्वरित तरीके पसंद करते हैं, तो हम pd.read_htmlअनुरोधों और सुंदरियों के पूरे नृत्य के बजाय बस उपयोग कर सकते हैं ।
भीषण पौडेल

4

यहाँ एक सामान्य उदाहरण के लिए काम कर रहा है <table>। ( प्रश्न लिंक-टूट )

सकल घरेलू उत्पाद (सकल घरेलू उत्पाद) द्वारा यहाँ के देशों से तालिका निकालना ।

htmltable = soup.find('table', { 'class' : 'table table-striped' })
# where the dictionary specify unique attributes for the 'table' tag

tableDataTextसमारोह एक एचटीएमएल खंड टैग के साथ शुरुआत पार्स करता है <table> कई द्वारा पीछा किया <tr>(तालिका पंक्तियों) और आंतरिक <td>(तालिका डेटा) टैग। यह आंतरिक स्तंभों के साथ पंक्तियों की एक सूची देता है। <th>पहली पंक्ति में केवल एक (टेबल हेडर / डेटा) को स्वीकार करता है ।

def tableDataText(table):       
    rows = []
    trs = table.find_all('tr')
    headerow = [td.get_text(strip=True) for td in trs[0].find_all('th')] # header row
    if headerow: # if there is a header row include first
        rows.append(headerow)
        trs = trs[1:]
    for tr in trs: # for every table row
        rows.append([td.get_text(strip=True) for td in tr.find_all('td')]) # data row
    return rows

इसके प्रयोग से हमें (पहली दो पंक्तियाँ) मिलती हैं।

list_table = tableDataText(htmltable)
list_table[:2]

[['Rank',
  'Name',
  "GDP (IMF '19)",
  "GDP (UN '16)",
  'GDP Per Capita',
  '2019 Population'],
 ['1',
  'United States',
  '21.41 trillion',
  '18.62 trillion',
  '$65,064',
  '329,064,917']]

इसे pandas.DataFrameऔर अधिक उन्नत उपकरणों के लिए आसानी से रूपांतरित किया जा सकता है ।

import pandas as pd
dftable = pd.DataFrame(list_table[1:], columns=list_table[0])
dftable.head(4)

पांडा DataFrame HTML तालिका आउटपुट


0
from behave import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
import pandas as pd
import requests
from bs4 import BeautifulSoup
from tabulate import tabulate

class readTableDataFromDB: 
    def LookupValueFromColumnSingleKey(context, tablexpath, rowName, columnName):
        print("element present readData From Table")
        element = context.driver.find_elements_by_xpath(tablexpath+"/descendant::th")
        indexrow = 1
        indexcolumn = 1
        for values in element:
            valuepresent = values.text
            print("text present here::"+valuepresent+"rowName::"+rowName)
            if valuepresent.find(columnName) != -1:
                 print("current row"+str(indexrow) +"value"+valuepresent)
                 break
            else:
                 indexrow = indexrow+1    

        indexvalue = context.driver.find_elements_by_xpath(
            tablexpath+"/descendant::tr/td[1]")
        for valuescolumn in indexvalue:
            valuepresentcolumn = valuescolumn.text
            print("Team text present here::" +
                  valuepresentcolumn+"columnName::"+rowName)
            print(indexcolumn) 
            if valuepresentcolumn.find(rowName) != -1:
                print("current column"+str(indexcolumn) +
                      "value"+valuepresentcolumn)
                break
            else:
                indexcolumn = indexcolumn+1

        print("index column"+str(indexcolumn))
        print(tablexpath +"//descendant::tr["+str(indexcolumn)+"]/td["+str(indexrow)+"]")
        #lookupelement = context.driver.find_element_by_xpath(tablexpath +"//descendant::tr["+str(indexcolumn)+"]/td["+str(indexrow)+"]")
        #print(lookupelement.text)
        return context.driver.find_elements_by_xpath(tablexpath+"//descendant::tr["+str(indexcolumn)+"]/td["+str(indexrow)+"]")

    def LookupValueFromColumnTwoKeyssss(context, tablexpath, rowName, columnName, columnName1):
        print("element present readData From Table")
        element = context.driver.find_elements_by_xpath(
            tablexpath+"/descendant::th")
        indexrow = 1
        indexcolumn = 1
        indexcolumn1 = 1
        for values in element:
            valuepresent = values.text
            print("text present here::"+valuepresent)
            indexrow = indexrow+1
            if valuepresent == columnName:
                print("current row value"+str(indexrow)+"value"+valuepresent)
                break

        for values in element:
            valuepresent = values.text
            print("text present here::"+valuepresent)
            indexrow = indexrow+1
            if valuepresent.find(columnName1) != -1:
                print("current row value"+str(indexrow)+"value"+valuepresent)
                break

        indexvalue = context.driver.find_elements_by_xpath(
            tablexpath+"/descendant::tr/td[1]")
        for valuescolumn in indexvalue:
            valuepresentcolumn = valuescolumn.text
            print("Team text present here::"+valuepresentcolumn)
            print(indexcolumn)
            indexcolumn = indexcolumn+1
            if valuepresent.find(rowName) != -1:
                print("current column"+str(indexcolumn) +
                      "value"+valuepresentcolumn)
                break
        print("indexrow"+str(indexrow))
        print("index column"+str(indexcolumn))
        lookupelement = context.driver.find_element_by_xpath(
            tablexpath+"//descendant::tr["+str(indexcolumn)+"]/td["+str(indexrow)+"]")
        print(tablexpath +
              "//descendant::tr["+str(indexcolumn)+"]/td["+str(indexrow)+"]")
        print(lookupelement.text)
        return context.driver.find_element_by_xpath(tablexpath+"//descendant::tr["+str(indexrow)+"]/td["+str(indexcolumn)+"]")
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.