1 (20.09.2012 09:00:56 отредактировано valet)

Появилась необходимость сократить большое количество урл-ов. Решил воспользоваться API от http://clck.ru (сокращатель урл-ов от яндкеса).

Чтобы получить короткую ссылку для нашего урл достаточно отправить get-запрос http://clck.ru/--?url=нашурл

Поэтому у меня в файле url.txt:

Можно воспользоваться wget'ом:

cat url.txt | xargs -t -P 5 -n1 wget --quiet -O - > url_short.txt

Здесь:
5 - это количество потоков
--quiet -O - режим при котором не скачиваются файлы (файлы скачивать не надо, надо сразу получать то, что отдается сервером при get-запросе)

В результате чего в файле url_short.txt будет примерно следующее:

Разбить тем же sed'ом на отдельные строки конечно не проблема, но вот мне хотелось бы сохранять через разделитель оригинальный урл, то есть получить что-то вроде такого:

То есть как я понимаю мне надо как-то заставить wget не только стягивать по урл-у и записывать ответ, а еще и записывать урл, по которому он тянет.
Но моих знаний не хватает, чтобы передать еще 1 параметр, который бы писался в результующий файл.

Надеюсь это элементарно на самом деле ab и кто-то мне подскажет.

2

Держи скриптик

#!/bin/bash

URLS="http://yandex.ru/
http://google.ru/
http://rambler.ru/"

rm url_short.txt
for URL in `echo "$URLS"`
do
    echo -n "$URL|" >> url_short.txt
    wget "http://clck.ru/--?url=$URL" --quiet -O - >> url_short.txt
    echo "\n" >> url_short.txt
done

3

Vascom пишет:

Держи скриптик

#!/bin/bash

URLS="http://yandex.ru/
http://google.ru/
http://rambler.ru/"

rm url_short.txt
for URL in `echo "$URLS"`
do
    echo -n "$URL|" >> url_short.txt
    wget "http://clck.ru/--?url=$URL" --quiet -O - >> url_short.txt
    echo "\n" >> url_short.txt
done

Спасибо конечно, но не совсем то, что нужно:
1. Однопоточно, соответственно будет очень долго отрабатывать если много урл-ов
2. Нужно чтение из файла с урл-ами, но не кидать же прямо в bash-скрипт 70 тысяч урл-ов (именно столько у меня)

4

как-то так, если не думать...

 Консоль:
alexander@goblin-book /tmp $ cat >url.txt
http://yandex.ru/
http://google.ru/
http://rambler.ru/
alexander@goblin-book /tmp $ cat url.txt | while read url; do echo -n "$url|"; wget --quiet -O - "http://clck.ru/--?url=$url"; echo; done
http://yandex.ru/|http://clck.ru/FjYZ
http://google.ru/|http://clck.ru/HYqE
http://rambler.ru/|http://clck.ru/1HkR

95% процентов проблем находятся между клавиатурой и стулом.

5

Fat-Zer пишет:

как-то так, если не думать...

 Консоль:
alexander@goblin-book /tmp $ cat >url.txt
http://yandex.ru/
http://google.ru/
http://rambler.ru/
alexander@goblin-book /tmp $ cat url.txt | while read url; do echo -n "$url|"; wget --quiet -O - "http://clck.ru/--?url=$url"; echo; done
http://yandex.ru/|http://clck.ru/FjYZ
http://google.ru/|http://clck.ru/HYqE
http://rambler.ru/|http://clck.ru/1HkR

Спасибо конечно, но тоже ж не то - ну однопоточно же, в том то и фишка, что надо многопоточно. Представляете сколько времени уйдет, чтобы собрать 60 тысяч сокращений.

Как это сделал я...
Написал php-скрипт, который принимая get-параметр l, вытягивает строку под номером l из файла с урл-ами, обращается curl'ом на clck.ru за укороченной ссылкой и дописывает в файл урл и укороченный урл через разделитель |.
Сформировал такой файл (ну не calc'ом же генерить последовательность ab):

#!/bin/bash
i=1
rm urls_for_short
while [ $i -lt 60459 ]
do
  echo "http://domen.ru/clck.php?l=$i" >> urls_for_short
  #echo $i >> urls_for_short
  i=$[$i+1]
done

Получил файл в формате:

Осталось только wget-ом многопоточно запустить дергания скрипта, что я и сделал в 200 потоков:

cat urls_for_short | xargs -t -P 200 -n1 wget --quiet -O -

В результате прошло минут 10 (точно не засекал) и я получил в файле свои 60 тысяч сокращений.

6

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

7

Vascom пишет:

И в первом посте многопоточность не была обязательным условием.

Возможно, я как-то не заострил на этом внимания, хотя мой пример был как раз многопоточный.

Vascom пишет:

Естественно наши скрипты были лишь примерами, доработать которые тебе надо было самому.

Да, спасибо за помощь. Ваши примеры меня натолкнули на решения вопроса.

Спасибо всем, тему можно перенести в решенные или закрыть.

8

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

Стоит задача многопоточно отправлять get-запросы по нужным урл-ам с использованием socks5 с авторизацией. Для реализации был выбран curl, так как wget не поддерживает socks5 тем более с авторизацией.

В упрощенном виде (если не использовать socks5) решается так:

cat urls.txt | xargs -t -P 20 -n1 curl

urls.txt - список урл-ов в формате:

-P 20 - количество потоков

И все это прекрасно работает - если в файле urls.txt только урл-ы (по одному слову в одной строке).
Ну вот если добавить параметры для подключения к socks5:

--socks5 xx.xx.xx.xx:1080 --proxy-user proxylogin1:proxyparol1 http://mydomen.ru/file1.txt
...
--socks5 xx.xx.xx.xx:1080 --proxy-user proxylogin100500:proxyparol100500 http://mydomen.ru/filen.txt

то конструкция

cat urls.txt | xargs -t -P 20 -n1 curl

уже не работает, потому что в вывод идут не строки целиком, а отдельные слова со строк (очевидно так работает cat), то есть отдельно --socks5, xx.xx.xx.xx:1080 и т.д. - соответственно ничего не работает.
Казалось бы можно задать параметры curl'а непосредственно при вызове, то есть так:

cat urls.txt | xargs -t -P 20 -n1 curl --socks5 xx.xx.xx.xx:1080 --proxy-user proxylogin1:proxyparol1

, но тогда я смогу использовать только один прокси, но стоит задача использовать случайный из 500 проксей при каждом отдельном подключении.
Пробовал сделать так:
в файле urls.txt - только урл-ы, в файле socks5.txt:

--socks5 xx.xx.xx.xx:1080 --proxy-user proxylogin1:proxyparol1
...
--socks5 xx.xx.xx.xx:1080 --proxy-user proxylogin500:proxyparol500

и пробовал такую конструкцию:

cat urls.txt | xargs -t -P 20 -n1 curl `cat socks5.txt | shuf -n1`

`cat socks5.txt | shuf -n1` - возвращает случайную строку, но срабатывает то 1 раз, поэтому прокси выбирается действительно случайно, но он один на все потоки.

Как бы задача сводится к одному из двух:
1. либо как-то организовать случайность выбора здесь в выделенном cat urls.txt | xargs -t -P 20 -n1 curl `cat socks5.txt | shuf -n1` чтобы срабатывало каждый раз, а не только 1 раз.
2. либо заставить как-то вместо cat urls.txt выводить данные именно построчно.

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

9

В общем вопрос решен. Не cat там виновник, а опция xargs -n которая задает максимальное количество считываемых параметров. В моем случае достаточно задать -n5 и все работает!
Тему можно закрывать.