Запрос веб-сайта с помощью Perl LWP :: Простота обработки онлайн-цен - PullRequest
3 голосов
/ 18 февраля 2011

В свое свободное время я пытался улучшить свои способности Perl, работая над сценарием, который использует LWP :: Simple, чтобы опросить страницы продукта одного конкретного сайта, чтобы проверить цены продуктов (я в некотором роде Perl нуб). Этот скрипт также сохраняет очень простое отставание от последней цены, замеченной для этого товара (поскольку цены часто меняются).

Мне было интересно, можно ли как-нибудь еще автоматизировать сценарий, чтобы мне не пришлось явно добавлять URL-адрес страницы в начальный хеш (т. Е. Сохранить массив ключевых терминов и выполнить поисковый запрос amazon, чтобы найти страница или цена?). Есть ли способ, которым я мог бы сделать это, если бы я не копировал поисковый URL Amazon и анализировал мои ключевые слова? (Я знаю, что обработка HTML с помощью регулярных выражений, как правило, плохая форма, я просто использовал его, так как мне нужен только один небольшой фрагмент данных).


#!usr/bin/perl
use strict;
use warnings;
use LWP::Simple;

my %oldPrice;
my %nameURL = (
    "Archer Season 1" => "http://www.amazon.com/Archer-Season-H-Jon-Benjamin/dp/B00475B0G2/ref=sr_1_1?ie=UTF8&qid=1297282236&sr=8-1",
    "Code Complete" => "http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/ref=sr_1_1?ie=UTF8&qid=1296841986&sr=8-1",
    "Intermediate Perl" => "http://www.amazon.com/Intermediate-Perl-Randal-L-Schwartz/dp/0596102062/ref=sr_1_1?s=books&ie=UTF8&qid=1297283720&sr=1-1",
    "Inglorious Basterds (2-Disc)" => "http://www.amazon.com/Inglourious-Basterds-Two-Disc-Special-Brad/dp/B002T9H2LK/ref=sr_1_3?ie=UTF8&qid=1297283816&sr=8-3"
);

if (-e "backlog.txt"){
    open (LOG, "backlog.txt");
    while(){
        chomp;
        my @temp = split(/:\s/);
        $oldPrice{$temp[0]} = $temp[1];
    }
close(LOG);
}

print "\nChecking Daily Amazon Prices:\n";
open(LOG, ">backlog.txt");
foreach my $key (sort keys %nameURL){
    my $content = get $nameURL{$key} or die;
    $content =~  m{\s*\$(\d+.\d+)} || die;
    if (exists $oldPrice{$key} && $oldPrice{$key} != $1){
        print "$key: \$$1 (Was $oldPrice{$key})\n";
    }
    else{
    print "\n$key: $1\n";
    }
    print LOG "$key: $1\n";
}
close(LOG);

Ответы [ 2 ]

3 голосов
/ 18 февраля 2011

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

  1. Карта имени-URL-адреса данные конфигурации . Получить его извне программы.
  2. Сохранять исторические данные в базе данных .
  3. Изучите XPath и используйте его для извлечения данных из HTML , это легко, если вы уже пользуетесь CSS-селекторами.

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

2 голосов
/ 18 февраля 2011

Я сделал простой скрипт для демонстрации автоматизации поиска Amazon. URL-адрес поиска для всех отделов был изменен с помощью экранированного поискового запроса. Остальная часть кода является простым синтаксическим анализом с HTML :: TreeBuilder . Структуру рассматриваемого HTML легко проверить с помощью метода dump (см. Закомментированную строку).

use strict; use warnings;

use LWP::Simple;
use URI::Escape;
use HTML::TreeBuilder;
use Try::Tiny;

my $look_for = "Archer Season 1";

my $contents
  = get "http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords="
        . uri_escape($look_for);

my $html = HTML::TreeBuilder->new_from_content($contents);
for my $item ($html->look_down(id => qr/result_\d+/)) {
    # $item->dump;      # find out structure of HTML
    my $title = try { $item->look_down(class => 'productTitle')->as_trimmed_text };
    my $price = try { $item->look_down(class => 'newPrice')->find('span')->as_text };

    print "$title\n$price\n\n";
}
$html->delete;
...