Как извлечь значения из таблицы без определяющих характеристик? - PullRequest
0 голосов
/ 09 мая 2019

Я пытаюсь получить номера деталей с веб-сайта перекрестных ссылок, но когда я проверяю элемент, единственными тегами, используемыми вокруг таблицы, являются tr, td, tbody и table, которые используются во многих других местах на странице. В настоящее время я использую Beautiful soup и selenium, и я собираюсь использовать lxml.html для его инструмента xpath, но я не могу заставить его работать с красивым супом.

Сайт, с которого я пытаюсь получить значения, https://jdparts.deere.com/servlet/com.deere.u90.jdparts.view.servlets.searchcontroller.PartialPartNumberSearchController?action=UNSIGNED_VIEW и технически мне нужны только значения номера детали, марки, номера детали, типа детали и описания, но я могу иметь дело с получением всей таблицы.

Когда я использую

html2 = browser.page_source
source = soup(html2, 'html.parser')
for article in source.find_all('td', valign='middle'):
    PartNumber = article.text.strip()
        number.append(PartNumber)

это дает мне все значения на странице и несколько пустых значений в одной строке текста, что будет такой же трудоемкой задачей, как и ручное извлечение значений.

В конечном итоге я надеюсь получить значения в таблице и отформатировать их так, чтобы они выглядели как таблица, и я могу просто удалить ненужные столбцы. Как лучше всего собирать информацию в таблице?

1 Ответ

0 голосов
/ 09 мая 2019

Один из подходов состоит в том, чтобы найти Qty., который является элементом в начале таблицы, которую вы хотите, и затем искать предыдущую таблицу.Затем вы можете перебрать элементы tr и получить строку значений из всех элементов td в каждой строке.

Здесь может пригодиться функция Python itemgetter(),поскольку он позволяет вам извлекать нужные элементы (в любом порядке) из большего списка.В этом примере я выбрал элементы 1,2,3,4,5, но если, скажем, Make не был необходим, вы могли бы предоставить 1,3,4,5.

Результаты поиска могут иметь несколько страниц результатов, если этоВ этом случае проверяется наличие кнопки Next Page, а при наличии - params для получения следующей страницы результатов.Это продолжается до тех пор, пока не будет найдена следующая страница:

from operator import itemgetter
import requests
from bs4 import BeautifulSoup
import csv


search_term = "AT2*"

params = {
    "userAction" : "search",
    "browse" : "",
    "screenName" : "partSearch",
    "priceIdx" : 1,
    "searchAppType" : "",
    "searchType" : "search",
    "partSearchNumber" : search_term,
    "pageIndex" : 1,
    "endPageIndex" : 100,
}

url = 'https://jdparts.deere.com/servlet/com.deere.u90.jdparts.view.servlets.searchcontroller.PartNumberSearch'
req_fields = itemgetter(1, 2, 3, 4, 5)
page_index = 1
session = requests.Session()
start_row = 0

with open('output.csv', 'w', newline='') as f_output:
    csv_output = csv.writer(f_output)

    while True:
        print(f'Page {page_index}')

        req = session.post(url, params=params)
        soup = BeautifulSoup(req.content, 'html.parser')
        table = soup.find(text='Qty.').find_previous('table')

        for tr in table.find_all('tr')[start_row:]:
            row = req_fields([value.get_text(strip=True) for value in tr.find_all('td')])

            if row[0]:
                csv_output.writerow(row)

        if soup.find(text='Next Page'):
            start_row = 2

            params = {
                "userAction" : "NextPage",
                "browse" : "NextPage",
                "pageIndex" : page_index,
                "endPageIndex" : 15,
            }
            page_index += 1

        else:
            break

Что даст вам файл output.csv, начинающийся с:

Part Number,Make,Part No.,Part Type,Description
AT2,Kralinator,PMTF15013,Filters,Filter
AT2,Kralinator,PMTF15013J,Filters,Filter
AT20,Berco,T139464,Undercarriage All Makes,Spring Pin
AT20061,A&I Products,A-RE29882,Clutch,Clutch Disk

Примечание. При этом вместо 1023 используется requestsselenium как будет намного быстрее.

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