Friday, January 27, 2012

Раскручиваем сайт злобоскриптом на питоне http://toly-blog.ru/programming/raskruchivaem-sajt-zloboskriptom-na-pitone/


Раскручиваем сайт злобоскриптом на питоне


По работе получил задание: раскрутить портал. Неправильная верстка, нетранслитная ссылочная структура конечно будут весомыми факторами отсутствия сайта в топе. Не менее весомым обстоятельством, влияющим на позиции портала, оказалось полное отсутствие ссылок с внешних ресурсов (я уже не говорю о близких по тематике). Решение этой задачи было решено автоматизировать.

Я предложил следующий вариант алгоритма своего злобоскрипта: пройтись по карте сайта, преобразовать ее в массив урлов (т.е. все доступные для индексации страницы сайта), из каждой страницы взять метаданные (теги description и keywords), осуществить по содержанию метатегов поиск (автоматический поиск легко реализовать в яндексе) что бы найти близкие по тематике страницы, для каждой из найденных страниц узнать PageRank сайта и есть ли в ней поля ввода (textarea), ну и соответственно сохранить все в лог-файл. После чего согласно лог-файла необходимо разместить ссылки (уже руками, а то доавтоматизируетесь тут мне ) по выданным адресам.

Идею оценили и я принялся за дело. В этой статье дабы не раскрывать коммерческой тайны (какие сайты мною раскручиваются) для наглядности (а заодно и для личной выгоды) пример рассмотрю применительно к раскрутке своего блога.

Что бы не валить все в одну кучу, разделим нашу задачу на несколько подзадач, а именно:

  1. Получение ссылок из карты сайта;
  2. Парсинг страницы на предмет метатегов (применительно к блогу будем обрабатывать заголовки);
  3. Парсинг выдачи поисковика по заданному запросу;
  4. Определение авторитетности страницы (или ресурса);
  5. Определение наличия полей ввода.

Оформим каждый из этих пунктов в виде функции и поместим их в отдельный модуль (я обозвал его seo.py):

 # -*- coding: utf-8  import re import string import urllib import urllib2  # проверка ссылки на поле ввода def checkinp(url):     if url[:7] != 'http://':         url = 'http://' + url     try:         page = urllib.urlopen(url).read()     except:         return False     else:         pass     return '<textarea' in page  # главный домен страницы def host(url):     if url[:7] == 'http://': 	url =  url[7:]     url = string.split(url, '/')[0]     return 'http://'+url  # поиск в яндексе # page - номер страницы поиска # numdoc - количество ссылок на странице (20, 50) def ypages(text, page=0, numdoc=10, results=[]):     host = "http://yandex.ru/yandsearch"     headers = { 'User-Agent' : 'Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.2.15 Version/10.00',     'Host' : 'ya.ru',     'Accept' : 'text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1',     'Accept-Language' : 'ru-RU,ru;q=0.9,en;q=0.8',     'Accept-Charset' : 'Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1',     'Referer' : 'http://www2.amit.ru/forum/index.php',     'Connection' : 'Keep-Alive, TE',     'TE' : 'TE: deflate, gzip, chunked, identity, trailers' }      if page != 0:     	url = urllib.urlencode({"p": str(page), "text": text, "lr":"77", "numdoc":str(numdoc)})     else:     	url = urllib.urlencode({"text": text, "lr":"77", "numdoc":str(numdoc)})     request = host+"?"+url     data = urllib2.urlopen(request)      txt = data.read()     links = re.findall(r'href="http://([^"]+)', txt)     for link in links:     	if 'yandex' not in link and link not in results:     	    results.append(link)     return results  # убираем частоповторяющиеся выражения (в заголовках) def del_strs(title):     not_words = ['-рецепты.', 'Модуль quotes.', 'Цитадель Зла', '.']     for word in not_words: 	if word in title:             title = string.replace(title, word, '')     return title  # получаем заголовок на странице def get_title(url):     page = urllib.urlopen(url).read()     titles = re.findall(r'<h2 class="title">([^<]+)', page)     return del_strs(titles[0])  # ссылки из карты сайта def sitemap_links(url):     sitemap = urllib.urlopen(url).read()     urls = re.findall(r'<loc>([^<]+)<', sitemap)     return urls  # эта и последующие функции - для вычисления pagerank def get_pagerank(url):     hsh = check_hash(hash_url(url))     gurl = 'http://www.google.com/search?client=navclient-auto&features=Rank:&q=info:%s&ch=%s' % (urllib.quote(url), hsh)     try:         f = urllib.urlopen(gurl)         rank = f.read().strip()[9:]     except Exception:         rank = 'N/A'     if rank == '':         rank = '0'     return rank  def  int_str(string, integer, factor):     for i in range(len(string)) :         integer *= factor         integer &= 0xFFFFFFFF         integer += ord(string[i])     return integer  def hash_url(string):     c1 = int_str(string, 0x1505, 0x21)     c2 = int_str(string, 0, 0x1003F)     c1 >>= 2     c1 = ((c1 >> 4) & 0x3FFFFC0) | (c1 & 0x3F)     c1 = ((c1 >> 4) & 0x3FFC00) | (c1 & 0x3FF)     c1 = ((c1 >> 4) & 0x3C000) | (c1 & 0x3FFF)     t1 = (c1 & 0x3C0) << 4     t1 |= c1 & 0x3C     t1 = (t1 << 2) | (c2 & 0xF0F)     t2 = (c1 & 0xFFFFC000) << 4     t2 |= c1 & 0x3C00     t2 = (t2 << 0xA) | (c2 & 0xF0F0000)     return (t1 | t2)  def check_hash(hash_int):     hash_str = '%u' % (hash_int)     flag = 0     check_byte = 0     i = len(hash_str) - 1     while i >= 0:         byte = int(hash_str[i])         if 1 == (flag % 2):             byte *= 2;             byte = byte / 10 + byte % 10         check_byte += byte         flag += 1         i -= 1     check_byte %= 10     if 0 != check_byte:         check_byte = 10 - check_byte         if 1 == flag % 2:             if 1 == check_byte % 2:                 check_byte += 9             check_byte >>= 1     return '7' + str(check_byte) + hash_str

А вот и основной скрипт:

 # -*- coding: utf-8 import seo import urllib  # имя файла-отчета (лог) fname = 'result.csv' # адрес карты сайта sitemap = 'http://toly-blog.ru/sitemap.xml' # функция занесения строки в лог-файл def log(st):     global fname     f = open(fname, 'a+')     f.write(st+'\n')     f.close()  # пишем в лог шапку таблицы log('pr_host;pr_page;url;link\n')  # считываем ссылки сайта из карты сайта urls = seo.sitemap_links(sitemap) # для каждой страницы сайта for url in urls:     print url     # определяем заголовок страницы     title = seo.get_title(url)     if title == 'Рубрики': 	continue     print title     # ищем заголовок в яндексе     links = seo.ypages(title)     # для каждой найденной страницы     for link in links: 	# если есть поля ввода 	if seo.checkinp(link):             # определяем ee pagerank              pr_page = str(seo.get_pagerank(link)) 	    # и pagerank ее хоста 	    pr_host = str(seo.get_pagerank(seo.host(link))) 	    # оформляем и пишем в лог 	    st = pr_host+';'+pr_page+';'+url+';'+link 	    log(st)

Запускаю скрипт и иду пить кофе…

SEO-zloboscript

SEO-zloboscript в работе

Попив кофе приходится налить вторую кружку: очень уж долго без многопоточности все работает.

И вот по окончании работы скрипта получаем аккуратный csv-файл из которого понятно куда какую ссылку можно оставить в комментариях:

Результат работы злобоскрипта

Результат работы злобоскрипта

Жду вопросов и комментариев. Так же хотелось бы услышать предложения по улучшению алгоритма скрипта.

P.S. В коде намеренно допущена ошибка (а может и несколько ошибок – не помню), которые не позволяют использовать скрипт на полную катушку.

P.S. 2 Пробую пробиться на хабр :)

P.S. 3 Не пускают :(

No comments:

Post a Comment