не удается получить пустую строку в список из Xpath

#python #web-scraping

Вопрос:

Я полный новичок. Я тренируюсь в разборе сайтов по заданиям на upwork. Проблема возникла следующим образом: список товаров возвращен в полном объеме, но не прейскурант, нет «текста» цены на новый самолет. Затем списки нужно объединить в таблицу, все идет не так без равного количества элементов в списках.

Пожалуйста, помогите мне узнать, как обрабатывать такие исключения, чтобы в этом случае в конечном списке появлялась пустая строка. Заранее спасибо за ваши ответы.

 import requests
import lxml.html


def parse_data(url):
    try:
        response = requests.get(url)
    except:
        return
    tree = lxml.html.document_fromstring(response.text)
    text_aicraft = tree.xpath('//*[contains(@id, "item_card")]/div/div[4]/div/h2/a/text()')
    price_aicraft = tree.xpath('//*[contains(@id, "item_card")]/div/div[4]/div/div[1]/text()')
    print(text_aicraft)
    print(len(text_aicraft))
    print(price_aicraft)
    print(len(price_aicraft))


def main():
    url = 'https://www.avbuyer.com/aircraft/private-jets/page-13'
    parse_data(url)


if __name__ == "__main__":
    main()
 

Ответ №1:

Этот скрипт будет перебирать каждый товар, и если цены нет, он заменяет ее N/A :

 import requests
import lxml.html


def parse_data(url):
    try:
        response = requests.get(url)
    except:
        return
    tree = lxml.html.document_fromstring(response.text)
    for item in tree.xpath('//*[contains(@class, "list-item-details")]'):
        title = item.xpath(".//h2/a/text()")[0]
        price = item.xpath('.//*[contains(@class, "price")]/text()')
        price = price[0] if price else "N/A"

        print("{:<40} {:<20}".format(title, price))

def main():
    url = "https://www.avbuyer.com/aircraft/private-jets/page-13"
    parse_data(url)


if __name__ == "__main__":
    main()
 

С принтами:

 Dassault Falcon 50EX                     Deal pending        
Cessna Citation M2                       Please call         
Embraer Phenom 300                       Please call         
Bombardier Learjet 40XR                  Please call         
Embraer Legacy 600                       Please call         
Cessna Citation Sovereign                Price: USD $6,500,000
Cessna Citation Ultra                    Please call         
Cessna Citation Ultra                    Please call         
Airbus ACJ318                            Make offer          
Gulfstream G550                          Please call         
Boeing 737 -500                          Please call         
Boeing BBJ                               Make offer          
Hawker 800XP                             Please call         
Boeing 737                               Price: USD $3,500,000
Bombardier Learjet 55                    Please email        
Bombardier Challenger 300                Make offer          
Airbus ACJ TwoTwenty                     N/A                 
Gulfstream G200                          Please call         
Bombardier Learjet 60XR                  Deal pending        
Cessna Citation Mustang                  Price: USD $1,200,000
 

Комментарии:

1. @jay.cs Не могли бы вы, пожалуйста, помочь еще с одной вещью. Как я могу получить URL-адрес для каждого самолета? Я попробовал это: href = item.xpath(".//h2/a")[0].attrib['href'] но он возвращает строку, похожую на «/самолеты/частные самолеты/бомбардировщик-learjet/55/361787», а не ссылку

2. @Копатыч Try href = "https://www.avbuyer.com" item.xpath(".//h2/a")[0].attrib['href']

3. Спасибо! Это работает. Если это возможно, еще один вопрос: я хочу экспортировать все данные в Excel. Но мой код перезаписывает файл с данными с последней очищенной страницы сайта и стирает все предыдущие строки. Пожалуйста, помогите мне упорядочить логику добавления каждой новой очищенной страницы в мой файл по одной. Еще раз спасибо вам за ваше время и знания. Вот мой код на данный момент:

4. @Копатыч Чтобы не загромождать раздел комментариев, я бы предложил открыть новый вопрос здесь, на StackOverflow. Я попытаюсь взглянуть на это.

Ответ №2:

Одним из вариантов было бы разделить синтаксический анализ на два этапа.

Шаг 1 — извлеките элементы. Шаг 2 — извлечение текста из элементов

Понимание списка Python возвращает значение «Нет», когда элемент пуст.

 import requests
import lxml.html


def parse_data(url):
    try:
        response = requests.get(url)
    except:
        return
    tree = lxml.html.document_fromstring(response.text)
    text_aicraft = tree.xpath('//*[contains(@id, "item_card")]/div/div[4]/div/h2/a/text()')
    price_aicraft_elements = tree.xpath('//*[contains(@id, "item_card")]/div/div[4]/div/div[1]')
    price_aicraft =  [element.text for element in price_aicraft_elements]
    print(text_aicraft)
    print(len(text_aicraft))
    print(price_aicraft)
    print(len(price_aicraft))


def main():
    url = 'https://www.avbuyer.com/aircraft/private-jets/page-13'
    parse_data(url)


if __name__ == "__main__":
    main()
 

Выход:

 ['Dassault Falcon 50EX ', 'Cessna Citation M2 ', 'Embraer Phenom 300 ', 'Bombardier Learjet 40XR ', 'Embraer Legacy 600 ', 'Cessna Citation Sovereign ', 'Cessna Citation Ultra ', 'Cessna Citation Ultra ', 'Airbus ACJ318 ', 'Gulfstream G550 ', 'Boeing 737 -500', 'Boeing BBJ ', 'Hawker 800XP ', 'Boeing
 737 ', 'Bombardier Learjet 55 ', 'Bombardier Challenger 300 ', 'Airbus ACJ TwoTwenty ', 'Gulfstream G200 ', 'Bombardier Learjet 60XR ', 'Cessna Citation Mustang ']
20
['Deal pending', 'Please call ', 'Please call ', 'Please call ', 'Please call ', 'Price: USD $6,500,000', 'Please call ', 'Please call ', 'Make offer', 'Please call ', 'Please call ', 'Make offer', 'Please call ', 'Price: USD $3,500,000', 'Please email', 'Make offer', None, 'Please call ', 'Deal pend
ing', 'Price: USD $1,200,000']
20
 

Комментарии:

1. Не могли бы вы, пожалуйста, помочь еще с одной вещью. Как я могу получить URL-адрес для каждого самолета? Я попробовал это: href = item.xpath(".//h2/a")[0].attrib['href'] но он возвращает строку, похожую на «/самолеты/частные самолеты/бомбардировщик-learjet/55/361787», а не ссылку