Erlang может сделать самый мощный веб-сканер сегодня. Позвольте мне рассказать вам о моем простом гусеничном шасси.
Шаг 1. Я создаю простой модуль параллелизма, который я называю mapreduce
-module(mapreduce).
-export([compute/2]).
%%=====================================================================
%% usage example
%% Module = string
%% Function = tokens
%% List_of_arg_lists = [["file\r\nfile","\r\n"],["muzaaya_joshua","_"]]
%% Ans = [["file","file"],["muzaaya","joshua"]]
%% Job being done by two processes
%% i.e no. of processes spawned = length(List_of_arg_lists)
compute({Module,Function},List_of_arg_lists)->
S = self(),
Ref = erlang:make_ref(),
PJob = fun(Arg_list) -> erlang:apply(Module,Function,Arg_list) end,
Spawn_job = fun(Arg_list) ->
spawn(fun() -> execute(S,Ref,PJob,Arg_list) end)
end,
lists:foreach(Spawn_job,List_of_arg_lists),
gather(length(List_of_arg_lists),Ref,[]).<br>
gather(0, _, L) -> L;
gather(N, Ref, L) ->
receive
{Ref,{'EXIT',_}} -> gather(N-1,Ref,L);
{Ref, Result} -> gather(N-1, Ref, [Result|L])
end.<br>
execute(Parent,Ref,Fun,Arg)->
Parent ! {Ref,(catch Fun(Arg))}.
Шаг 2. HTTP-клиент
Обычно можно использовать либо inets httpc module
, встроенный в erlang, либо <a href="https://github.com/cmullaparthi/ibrowse" rel="noreferrer">ibrowse</a>
. Однако, для управления памятью и скорости (получение минимального отпечатка памяти), хороший программист на эрланге мог бы выбрать <a href="http://curl.haxx.se/docs/manual.html" rel="noreferrer">curl</a>
. Применяя <a href="http://www.erlang.org/doc/man/os.html#cmd-1" rel="noreferrer">os:cmd/1</a>
, который принимает эту командную строку curl, можно получить вывод непосредственно в вызывающую функцию erlang. Тем не менее, лучше, чтобы curl перебрасывал свои выходные данные в файлы, и тогда у нашего приложения есть другой поток (процесс), который считывает и анализирует эти файлы
<b>Command</b>: curl "http://www.erlang.org" -o "/downloaded_sites/erlang/file1.html"<br>
<b>In Erlang</b><br>
os:cmd("curl \"http://www.erlang.org\" -o \"/downloaded_sites/erlang/file1.html\"").
Так что вы можете порождать много процессов. Вы не забыли экранировать URL-адрес, а также путь к выходному файлу при выполнении этой команды. С другой стороны, существует процесс, работа которого заключается в просмотре каталога загруженных страниц. Эти страницы он читает и анализирует, может затем удалить после разбора или сохранить в другом месте или, что еще лучше, заархивировать их, используя
zip module
folder_check()->
spawn(fun() -> check_and_report() end),
ok.
-define(CHECK_INTERVAL,5).
check_and_report()->
%% avoid using
%% filelib:list_dir/1
%% if files are many, memory !!!
case os:cmd("ls | wc -l") of
"0\n" -> ok;
"0" -> ok;
_ -> ?MODULE:new_files_found()
end,
sleep(timer:seconds(?CHECK_INTERVAL)),
%% keep checking
check_and_report().
new_files_found()->
%% inform our parser to pick files
%% once it parses a file, it has to
%% delete it or save it some
%% where else
gen_server:cast(?MODULE,files_detected).
Шаг 3. HTML-парсер.
Лучше используйте это <a href="http://ppolv.wordpress.com/2008/05/09/fun-with-mochiwebs-html-parser-and-xpath/" rel="noreferrer">mochiweb's html parser and XPATH</a>
. Это поможет вам разобрать и получить все ваши любимые теги HTML, извлечь содержимое, а затем все готово. В примерах ниже я сосредоточился только на Keywords
, description
и title
в разметке
Проверка модуля в оболочке ... потрясающие результаты !!!
2> spider_bot:parse_url("http://erlang.org").
[[[],[],
{"keywords",
"erlang, functional, programming, fault-tolerant, distributed, multi-platform, portable, software, multi-core, smp, concurrency "},
{"description","open-source erlang official website"}],
{title,"erlang programming language, official website"}]
3> spider_bot:parse_url("http://facebook.com").
[[{"description",
" facebook is a social utility that connects people with friends and others who work, study and live around them. people use facebook to keep up with friends, upload an unlimited number of photos, post links
and videos, and learn more about the people they meet."},
{"robots","noodp,noydir"},
[],[],[],[]],
{title,"incompatible browser | facebook"}]
4> spider_bot:parse_url("http://python.org").
[[{"description",
" home page for python, an interpreted, interactive, object-oriented, extensible\n programming language. it provides an extraordinary combination of clarity and\n versatility, and is free and
comprehensively ported."},
{"keywords",
"python programming language object oriented web free source"},
[]],
{title,"python programming language – official website"}]
5> spider_bot:parse_url("http://www.house.gov/").
[[[],[],[],
{"description",
"home page of the united states house of representatives"},
{"description",
"home page of the united states house of representatives"},
[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],
[],[],[]|...],
{title,"united states house of representatives, 111th congress, 2nd session"}]
Теперь вы можете понять, что мы можем индексировать страницы по их ключевым словам, плюс хороший график просмотра страниц. Другая проблема заключалась в том, как создать сканер (то, что будет перемещаться по всей сети, от домена к домену), но это легко. Это возможно, анализируя HTML-файл для тегов href. Сделайте HTML Parser для извлечения всех тегов href, и тогда вам могут понадобиться некоторые регулярные выражения здесь и там, чтобы получить ссылки прямо под данным доменом.
Запуск гусеничного механизма
7> spider_connect:conn2("http://erlang.org").
Links: ["http://www.erlang.org/index.html",
"http://www.erlang.org/rss.xml",
"http://erlang.org/index.html","http://erlang.org/about.html",
"http://erlang.org/download.html",
"http://erlang.org/links.html","http://erlang.org/faq.html",
"http://erlang.org/eep.html",
"http://erlang.org/starting.html",
"http://erlang.org/doc.html",
"http://erlang.org/examples.html",
"http://erlang.org/user.html",
"http://erlang.org/mirrors.html",
"http://www.pragprog.com/titles/jaerlang/programming-erlang",
"http://oreilly.com/catalog/9780596518189",
"http://erlang.org/download.html",
"http://www.erlang-factory.com/conference/ErlangUserConference2010/speakers",
"http://erlang.org/download/otp_src_R14B.readme",
"http://erlang.org/download.html",
"https://www.erlang-factory.com/conference/ErlangUserConference2010/register",
"http://www.erlang-factory.com/conference/ErlangUserConference2010/submit_talk",
"http://www.erlang.org/workshop/2010/",
"http://erlangcamp.com","http://manning.com/logan",
"http://erlangcamp.com","http://twitter.com/erlangcamp",
"http://www.erlang-factory.com/conference/London2010/speakers/joearmstrong/",
"http://www.erlang-factory.com/conference/London2010/speakers/RobertVirding/",
"http://www.erlang-factory.com/conference/London2010/speakers/MartinOdersky/",
"http://www.erlang-factory.com/",
"http://erlang.org/download/otp_src_R14A.readme",
"http://erlang.org/download.html",
"http://www.erlang-factory.com/conference/London2010",
"http://github.com/erlang/otp",
"http://erlang.org/download.html",
"http://erlang.org/doc/man/erl_nif.html",
"http://github.com/erlang/otp",
"http://erlang.org/download.html",
"http://www.erlang-factory.com/conference/ErlangUserConference2009",
"http://erlang.org/doc/efficiency_guide/drivers.html",
"http://erlang.org/download.html",
"http://erlang.org/workshop/2009/index.html",
"http://groups.google.com/group/erlang-programming",
"http://www.erlang.org/eeps/eep-0010.html",
"http://erlang.org/download/otp_src_R13B.readme",
"http://erlang.org/download.html",
"http://oreilly.com/catalog/9780596518189",
"http://www.erlang-factory.com",
"http://www.manning.com/logan",
"http://www.erlang.se/euc/08/index.html",
"http://erlang.org/download/otp_src_R12B-5.readme",
"http://erlang.org/download.html",
"http://erlang.org/workshop/2008/index.html",
"http://www.erlang-exchange.com",
"http://erlang.org/doc/highlights.html",
"http://www.erlang.se/euc/07/",
"http://www.erlang.se/workshop/2007/",
"http://erlang.org/eep.html",
"http://erlang.org/download/otp_src_R11B-5.readme",
"http://pragmaticprogrammer.com/titles/jaerlang/index.html",
"http://erlang.org/project/test_server",
"http://erlang.org/download-stats/",
"http://erlang.org/user.html#smtp_client-1.0",
"http://erlang.org/user.html#xmlrpc-1.13",
"http://erlang.org/EPLICENSE",
"http://erlang.org/project/megaco/",
"http://www.erlang-consulting.com/training_fs.html",
"http://erlang.org/old_news.html"]
ok
Хранение: Является одним из наиболее важных понятий для поисковой системы. Большая ошибка - хранить данные поисковой системы в таких СУБД, как MySQL, Oracle, MS SQL и т. Д. Такие системы полностью сложны, и приложения, которые взаимодействуют с ними, используют эвристические алгоритмы. Это приводит нас к
хранилищам ключевых значений , из которых два моих лучших -
<a href="http://www.couchbase.com/" rel="noreferrer">Couch Base Server</a>
и
<a href="http://basho.com/" rel="noreferrer">Riak</a>
. Это отличные облачные файловые системы. Другим важным параметром является кеширование. Кеширование достигается, скажем,
<b><a href="http://memcached.org/" rel="noreferrer">Memcached</a></b>
, из которых две другие системы хранения, упомянутые выше, поддерживают его. Системы хранения для поисковых систем должны быть
schemaless DBMS
, которые ориентированы на
Availability rather than Consistency
. Узнайте больше о поисковых системах здесь:
http://en.wikipedia.org/wiki/Web_search_engine