Написание парсера с помощью ChatGPT. Насколько это хорошо?

Написание парсера с помощью ChatGPT. Насколько это хорошо?

17 апреля 2023 г.

В ноябре, после того как OpenAI выпустила ChatGPT на основе GPT-3.5, новости о нем распространились со скоростью лесного пожара. В связи с этим я написал об искусственном интеллекте и парсинге веб-страниц, а затем спросил собеседников, что они думают. внимание было уделено состоянию искусственного интеллекта для индустрии парсинга веб-страниц.

Пять месяцев спустя у нас есть GPT-4 и множество приложений, созданных на основе моделей GPT, так что пришло время поближе познакомиться с искусственным интеллектом для парсинга веб-страниц.

a close up of a computer screen with the word chat on it

Может ли ИИ писать парсеры для нас?

В настоящий момент мы не можем ожидать, что ChatGPT напишет для нас полностью работающий парсер на выбранном веб-сайте. Он вернет синтаксически правильный парсер, но с универсальными селекторами, бесполезными в нашем случае. Если мы попросим очистить какой-нибудь известный веб-сайт, возможно, он сможет вернуть правильное сопоставление, если ответ уже был дан где-то в прошлом, например, в Stackoverflow.

Учитывая это, давайте попробуем создать парсер с нуля с помощью ChatGPT для нишевого веб-сайта, такого как https://www.gianvitorossi.com/it_it/

Я перейду прямо к последней подсказке, которую я написал, чтобы получить правильный паук Scrapy, где я попросил сопоставить четыре поля и объяснил ChatGPT план доступа к веб-сайту.

<цитата>

Создайте веб-парсер Python, используя платформу Scrapy и селекторы XPath.

Параметр start_urls должен содержать URL-адрес [https://www.gianvitorossi.com/it_it](https://www.gianvitorossi.com/it_it), который необходимо очистить.

После очистки первой страницы парсер должен ввести функцию get_categories.

В этой функции парсер извлекает все относительные ссылки на разные типы продуктов, используя следующий селектор XPath: product_pages = response.xpath('//a[@role="menuitem"]/@href').extract()

Для каждой страницы продукта следует ввести функцию get_product_list.

Извлеките список продуктов на странице с помощью селектора XPath (’//a[contains(@class, «b-product_tile-image_link»)]/@href).

Если нужно показать больше продуктов, перейдите на следующую страницу продукта, используя XPath ('//a[data-event-click.prevent="loadMore"]/@href).extract()[0], который содержит абсолютный путь к следующей странице и включить этот селектор в предложение try/except. Если совпадения для селектора нет, в предложении exclude следует использовать инструкцию pass.

Для каждого извлеченного продукта введите функцию get_product_details.

Напишите логику очистки следующих полей:

- код продукта

- полная_цена

- цена

– product_url

Страница сведений о продукте содержит JSON, содержащий большую часть необходимых нам данных. Его можно найти, ища первое вхождение скрипта type="application/ld+json" и извлекая оттуда текст.

Он следует стандартному типу Product [Schema.org](http://schema.org/), и вы можете сопоставить поле product_code с полем mpn Json.

Цену поля можно сопоставить, введя словарь предложений в JSON и выбрав поле цены.

Вместо этого поле product_url можно сопоставить с помощью значения response.url.

Так как на этом сайте нет скидок, поле full_price может отображаться как поле цены.

А вот код, указанный в ответе:

import scrapy
import json

class GianvitoRossiSpider(scrapy.Spider):
    name = 'gianvitorossi'
    start_urls = ['https://www.gianvitorossi.com/it_it']

    def parse(self, response):
        # Extract product categories
        product_pages = response.xpath('//a[@role="menuitem"]/@href').extract()
        for product_page in product_pages:
            yield scrapy.Request(response.urljoin(product_page), callback=self.get_product_list)

    def get_product_list(self, response):
        # Extract product links
        product_links = response.xpath('//a[contains(@class, "b-product_tile-image_link")]/@href')
        for link in product_links:
            yield scrapy.Request(response.urljoin(link.extract()), callback=self.get_product_details)

        # Check for more product pages
        try:
            next_page = response.xpath('//a[data-event-click.prevent="loadMore"]/@href').extract()[0]
            yield scrapy.Request(response.urljoin(next_page), callback=self.get_product_list)
        except:
            pass

    def get_product_details(self, response):
        # Extract JSON data
        json_data = response.xpath('//script[@type="application/ld+json"]/text()').extract_first()
        data = json.loads(json_data)

        # Extract product details
        product_code = data['mpn']
        full_price = data['offers']['price']
        price = full_price
        product_url = response.url

        # Return item
        yield {
            'product_code': product_code,
            'full_price': full_price,
            'price': price,
            'product_url': product_url
        }

Парсер работает правильно и извлекает все элементы. Но разве на написание подсказки, необходимой для создания паука, уходит меньше времени, чем на написание паука самостоятельно? Трудно сказать. В обоих случаях мне нужно записать селекторы XPath, поэтому ИИ не экономит мне время. Предположим, у нас есть правильно спроектированная подсказка и шаблон паука Scrapy для повторного использования, мы можем предположить, что время, затрачиваемое на изменение подсказки или скребка, одинаково. Единственным улучшением процесса является то, что ChatGPT написал парсер без каких-либо ошибок.

Исправление ошибок с ИИ

Давайте проверим полезность ChatGPT, когда столкнемся с ошибкой в ​​наших парсерах. Я изменю предыдущего паука, удалив цитату из Xpath и изменив имя неинициированной переменной.

    def get_product_details(self, response):

        # Extract JSON data

        json_data = response.xpath('//script[@type="application/ld+json"]/text()).extract_first()

        data = json.loads(json_data)

        # Extract product details

        product_code = data['mpn']

        full_price = data['offers']['price']

        price = full_price

        product_url = response.url

        # Return item

        yield {

            'product_code': product_code3,

            'full_price': full_price,

            'price': price,

            'product_url': product_url

        }

Сможет ли ChatGPT это исправить?

Да и не только вернул исправленный код, но и объяснил, что исправил.

<цитата>

Ошибка в исходном коде была синтаксической ошибкой в ​​селекторе XPath, используемом для извлечения данных JSON. Закрывающая кавычка была помещена неправильно, что привело к недопустимому селектору. Исправленный код помещает закрывающую кавычку в правильное место, позволяя селектору правильно извлекать данные JSON. Кроме того, в названии поля product_code в операторе yield была опечатка, которая была исправлена ​​в исправленном коде.

Это полезный способ использования ChatGPT, поскольку иногда мы тратим много времени на поиск решения этих глупых ошибок.

Перенос на другой язык

Вместо того, чтобы создавать парсер с помощью Python, я использовал ту же подсказку для создания парсера Node.js. Я ничего не знаю об этом языке, и посмотрим, сможет ли ChatGPT помочь мне в создании моего первого парсера на Node.js

Вот результат:

const axios = require('axios');
const cheerio = require('cheerio');

const startUrl = 'https://www.gianvitorossi.com/it_it';

async function scrape(url) {
  try {
    const response = await axios.get(url);
    const $ = cheerio.load(response.data);

    // Extract product categories
    const productPages = $('a[role="menuitem"]').map(function() {
      return $(this).attr('href');
    }).get();

    for (const productPage of productPages) {
      await getProducts(`https://www.gianvitorossi.com${productPage}`);
    }
  } catch (error) {
    console.error(error);
  }
}

async function getProducts(url) {
  try {
    const response = await axios.get(url);
    const $ = cheerio.load(response.data);

    // Extract product links
    const productLinks = $('a.b-product_tile-image_link').map(function() {
      return $(this).attr('href');
    }).get();

    for (const link of productLinks) {
      await getProductDetails(`https://www.gianvitorossi.com${link}`);
    }

    // Check for more product pages
    try {
      const nextPage = $('a[data-event-click.prevent="loadMore"]').attr('href');
      await getProducts(`https://www.gianvitorossi.com${nextPage}`);
    } catch (error) {
      // No more product pages
    }
  } catch (error) {
    console.error(error);
  }
}

async function getProductDetails(url) {
  try {
    const response = await axios.get(url);
    const $ = cheerio.load(response.data);

    // Extract JSON data
    const jsonText = $('script[type="application/ld+json"]')[0].children[0].data;
    const data = JSON.parse(jsonText);

    // Extract product details
    const productCode = data.mpn;
    const fullPrice = data.offers.price;
    const price = fullPrice;
    const productUrl = response.config.url;

    // Output data
    console.log({
      productCode: productCode,
      fullPrice: fullPrice,
      price: price,
      productUrl: productUrl
    });
  } catch (error) {
    console.error(error);
  }
}

scrape(startUrl);

Это здорово. Скребок исправен и работает отлично.

Заключительные замечания

Должен признаться, я впечатлен результатами этих тестов. Хотя это правда, что это не сэкономило мне много времени, когда я написал парсер Python, это позволило мне написать парсер Node.js.

ИИ может снизить барьеры для принятия нового языка и помочь в разработке парсеров, продолжая его изучать, а также помогая отлаживать написанный код. Это не заменяет старую добрую практическую практику, но помогает быстрее учиться.

В конце концов, ИИ на данный момент больше, чем помощь, чем угроза, которая может заменить человека в ближайшем будущем.


:::информация Также опубликовано здесь.

:::


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE