পাইথন বিউটিফুলসুফ পার্সিং টেবিল


89

আমি পাইথন requestsএবং বিউটিফুলসুপ শিখছি । অনুশীলনের জন্য, আমি একটি দ্রুত এনওয়াইসি পার্কিং টিকিট পার্সার লিখতে বেছে নিয়েছি। আমি এইচটিএমএল প্রতিক্রিয়া পেতে সক্ষম হয়েছি যা বেশ কুৎসিত। আমার lineItemsTableটিকিট কেড়ে নিয়ে পার্স করা দরকার ।

আপনি এখানে গিয়ে পৃষ্ঠাটি পুনঃ উত্পাদন করতে পারেন: https://paydirect.link2gov.com/NYCParking-Plate/ItemSearchএবং একটি NYপ্লেট প্রবেশ করে enteringT630134C

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আমাকে কোথাও পায় না।


কাছাকাছি পড়তে, আমি আসলে আপনার প্রশ্নটি কি তা নিশ্চিত নই। আপনার ঠিক কোন অংশে সাহায্যের প্রয়োজন তা আপনি পরিষ্কার করতে পারেন?
টিএমএল

প্রশ্ন লিঙ্ক-ভাঙ্গা: জেনেরিক <টেবিল> এর জন্য একটি কার্যকর উদাহরণকে প্রশ্রয় দিন
ইউসুব্রাসিলেরো

উত্তর:


173

আপনি এখানে যান:

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

@ ক্যামাগ আপনি কি সুন্দর স্যুপ 4 ব্যবহার করছেন?
শক্তিমান

4
প্রতিস্থাপন find_allসঙ্গেfindAll
user2314737

4
@ ব্যবহারকারী 2314737 বিএস উটের কেস এবং আন্ডারস্কোর স্বরলিপি উভয় সমর্থন করে। আমি পাইথন কোডিং নির্দেশিকা অনুসারে আন্ডারস্কোর ব্যবহার করি।
শক্তিমান

4
ঠিক আছে আমি আমার ত্রুটিটি সমাধান করেছি: এইচটিএমএল এর পরিদর্শন করে এটি টিডি দেখায়, যাইহোক, যখন আমি এর মূল্য মুদ্রিত করি তখন table = soup.find('table', attrs={'class':'analysis'})সেখানে কোনও লোক দেখায় নি, তাই সহজভাবে টিডি এবং টিআর অনুসন্ধান করে কাজটি করেছিল। সুতরাং আমার মতে ত্রুটি হওয়ার কারণ AttributeError: 'NoneType' object has no attribute 'find_all'হ'ল আমরা যখন কোনও ট্যাগ বা ক্ষেত্রটি পাস করি যা পৃষ্ঠার এইচটিএমএলতে নেই।
উমেশ কৌশিক

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

আপডেট: 2020

যদি কোনও প্রোগ্রামার ওয়েবপেজ থেকে কেবল টেবিল বিশ্লেষণ করতে আগ্রহী হয় তবে তারা পান্ডাস পদ্ধতিটি ব্যবহার করতে পারে pandas.read_html

ধরা যাক আমরা ওয়েবসাইট থেকে জিডিপি ডেটা টেবিলটি বের করতে চাই: https://worldpopulationreview.com/countries/countries-by-gdp/#worldCountries

তারপরে কোডগুলি নিখুঁতভাবে কাজ করে (সুন্দরদ্বীপ এবং অভিনব এইচটিএমএলের কোনও প্রয়োজন নেই):

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

4
আপনি যদি ইতিমধ্যে আপনার প্রকল্পের কোথাও পান্ডা ব্যবহার করেন। একটি টেবিলের জন্য খুব বেশি নির্ভরতা
Яхницкий

হাহাহা আপনি আমার নমুনা নমুনা অনুলিপি এবং উত্তর উন্নত। ঠিক আছে, কমপক্ষে আমি জানতে পছন্দ করেছিলাম যে পান্ডাদের এমন পদ্ধতি রয়েছে। সুন্দর!
ইউসুব্র্যাসিলিও

হ্যাঁ, আমি আপনার উদাহরণ থেকে জিডিপির ডেটা ইউআরএল ব্যবহার করেছি। হ্যাঁ আপনি যদি দ্রুত পদ্ধতি পছন্দ করেন তবে আমরা pd.read_htmlঅনুরোধ এবং সুন্দরসুপের পুরো নাচের পরিবর্তে কেবল ব্যবহার করতে পারি ।
ভিশন পৌদেল

4

জেনেরিকের জন্য এখানে কাজ করার উদাহরণ রয়েছে <table>। ( প্রশ্ন লিঙ্ক-ভাঙ্গা )

জিডিপি (গ্রস ডোমেস্টিক প্রোডাক্ট) দ্বারা এখানকার দেশগুলি থেকে টেবিলটি সরিয়ে নেওয়া ।

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

দ্য tableDataTextফাংশন একটি HTML সেগমেন্ট ট্যাগ দিয়ে শুরু parses <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)

পান্ডাস ডেটা ফ্রেম এইচটিএমএল টেবিল আউটপুট


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)+"]")
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.