Python BeautifulSoup, как я могу получить данные для последнего селектора - PullRequest
0 голосов
/ 22 декабря 2018

После отправки HTTP-запроса python его ответ (данные) содержит html-страницу, содержащую множество блоков ABCD.Вот один фрагмент

                   <tr>
                        <td class="success"></td>
                        <td class="truncate">ABCD</td>
                        <td>12/18/2018 21:45</td>
                        <td>12/18/2018 21:46</td>
                        <td>10</td>
                        <td>10</td>
                        <td>100.0</td>
                        <td><span class="label success">Success</span></td>
                        <td>SMS</td>
                        <td>
                            <a data-id="134717" class="btn" title="Go">View</a>
                        </td>
                    </tr>

Мне нужно получить самый последний идентификатор данных для ABCD (в данном случае 134717, и этот номер является динамическим).Также обратите внимание, что есть много таких ABCD с разными датами, я хочу самые последние.

Я могу сделать это, используя регулярное выражение и проходя построчно.Но я думаю, что лучше сделать это с BeautifulSoup.

Я пробовал это, он находит все ABCD, но я не знаю, как получить самый последний:

    soup = BeautifulSoup(data, "html.parser")
    for i in soup.select("td.truncate"):
        #print(i.text)
        if i.text == "ABCD":
            print ("Got it ", i.text)
            id1 = soup.select_one("a.data-id")
            print (id1)
            parsed_url1 = urlparse(id1)

Ответы [ 3 ]

0 голосов
/ 22 декабря 2018

при условии, что html следует той же схеме:

учитывая:

html = '''                   <tr>
                        <td class="success"></td>
                        <td class="truncate">ABCD</td>
                        <td>12/18/2018 21:45</td>
                        <td>12/18/2018 21:46</td>
                        <td>10</td>
                        <td>10</td>
                        <td>100.0</td>
                        <td><span class="label success">Success</span></td>
                        <td>SMS</td>
                        <td>
                            <a data-id="134717" class="btn" title="Go">View</a>
                        </td>
                    </tr>


                    <tr>
                        <td class="success"></td>
                        <td class="truncate">ABCD</td>
                        <td>12/20/2018 21:45</td>
                        <td>12/20/2018 21:46</td>
                        <td>99</td>
                        <td>99</td>
                        <td>999.0</td>
                        <td><span class="label success999">Success</span></td>
                        <td>SMS99</td>
                        <td>
                            <a data-id="9913471799" class="btn" title="Go">View</a>
                        </td>
                    </tr>

                                        <tr>
                        <td class="success"></td>
                        <td class="truncate">ABCD</td>
                        <td>12/22/2018 21:45</td>
                        <td>12/22/2018 21:46</td>
                        <td>99</td>
                        <td>99</td>
                        <td>999.0</td>
                        <td><span class="label success999">Success</span></td>
                        <td>SMS99</td>
                        <td>
                            <a data-id="found the latest date" class="btn" title="Go">View</a>
                        </td>
                    </tr>

                                        <tr>
                        <td class="success"></td>
                        <td class="truncate">ABCD</td>
                        <td>12/21/2018 21:45</td>
                        <td>12/21/2018 21:46</td>
                        <td>99</td>
                        <td>99</td>
                        <td>999.0</td>
                        <td><span class="label success999">Success</span></td>
                        <td>SMS99</td>
                        <td>
                            <a data-id="9913471799" class="btn" title="Go">View</a>
                        </td>
                    </tr>'''

найти самую последнюю дату:

import bs4
import re
import datetime                

dates_list = []

soup = bs4.BeautifulSoup(html, 'html.parser')

for i in soup.select("td.truncate"):
        #print(i.parent.text)
        match = re.search(r'\d{2}/\d{2}/\d{4}', i.parent.text)
        date = datetime.datetime.strptime(match.group(), '%m/%d/%Y').date()
        date = date.strftime('%m/%d/%Y')
        dates_list.append(date)

dates_list.sort()        
most_recent = dates_list[-1]

rows = soup.find_all('tr')
for row in rows:
    if str(most_recent) in row.text:
        id1 = row.find("a").get('data-id')  
        print (id1)
0 голосов
/ 22 декабря 2018

Если число data-id увеличивается, вы можете выбрать тег a с наибольшим значением data-id с max().

recentDataID = max([x.get('data-id') for x  in soup.select("a[data-id]")])
print(recentDataID)

# if you want to select the parent or `tr`
mostRecentRow = soup.select_one('a[data-id=%s]' % recentDataID).parent.parent
0 голосов
/ 22 декабря 2018

Для этого вам понадобится парсер dateutils .Очевидно, что нет способа определить, какая <td> содержит дату в ней, поэтому вам просто нужно перебрать все td в совпадающих tr и попытаться проанализировать datetime, и если разбор datetime был успешным, просто добавьте его всписок дат для определенного идентификатора.После того, как вы набрали все даты для каждого удостоверения личности, вы просто макс на них, чтобы найти последние.

from dateutil import parser as du_parser    
from collections import defaultdict
from bs4 import BeautifulSoup as BS

data = "<tr><td class=\"success\"></td><td class=\"truncate\">ABCD</td><td>12/18/2018 21:45</td><td>12/18/2018 21:46</td><td>10</td><td>10</td><td>100.0</td><td><span class=\"label success\">Success</span></td><td>SMS</td><td><a data-id=\"134717\" class=\"btn\" title=\"Go\">View</a></td></tr>"
b1 = BS(data, "html.parser")

td_of_interest = b1.find_all("td")
tr_that_contain_our_td = [x.parent for x in b1.find_all("td", string="ABCD")]

ids_dict = defaultdict(list)

# iterate over matched tr's to get their dates
for tr in tr_that_contain_our_td:
    extracted_id = tr.find("a")['data-id']

    for td in tr.find_all("td"):
        try:
            if len(td.contents) > 0:
                actual_date = du_parser.parse(td.contents[0])
                ids_dict[extracted_id].append(actual_date)
        except ValueError:
            pass  #nothing to do here

ids_dict = {k: max(v) for k, v in ids_dict.items()}

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