Раскручиваем сайт злобоскриптом на питоне
По работе получил задание: раскрутить портал. Неправильная верстка, нетранслитная ссылочная структура конечно будут весомыми факторами отсутствия сайта в топе. Не менее весомым обстоятельством, влияющим на позиции портала, оказалось полное отсутствие ссылок с внешних ресурсов (я уже не говорю о близких по тематике). Решение этой задачи было решено автоматизировать.
Я предложил следующий вариант алгоритма своего злобоскрипта: пройтись по карте сайта, преобразовать ее в массив урлов (т.е. все доступные для индексации страницы сайта), из каждой страницы взять метаданные (теги description и keywords), осуществить по содержанию метатегов поиск (автоматический поиск легко реализовать в яндексе) что бы найти близкие по тематике страницы, для каждой из найденных страниц узнать PageRank сайта и есть ли в ней поля ввода (textarea), ну и соответственно сохранить все в лог-файл. После чего согласно лог-файла необходимо разместить ссылки (уже руками, а то доавтоматизируетесь тут мне ) по выданным адресам.
Идею оценили и я принялся за дело. В этой статье дабы не раскрывать коммерческой тайны (какие сайты мною раскручиваются) для наглядности (а заодно и для личной выгоды) пример рассмотрю применительно к раскрутке своего блога.
Что бы не валить все в одну кучу, разделим нашу задачу на несколько подзадач, а именно:
- Получение ссылок из карты сайта;
- Парсинг страницы на предмет метатегов (применительно к блогу будем обрабатывать заголовки);
- Парсинг выдачи поисковика по заданному запросу;
- Определение авторитетности страницы (или ресурса);
- Определение наличия полей ввода.
Оформим каждый из этих пунктов в виде функции и поместим их в отдельный модуль (я обозвал его 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)
Запускаю скрипт и иду пить кофе…
Попив кофе приходится налить вторую кружку: очень уж долго без многопоточности все работает.
И вот по окончании работы скрипта получаем аккуратный csv-файл из которого понятно куда какую ссылку можно оставить в комментариях:
Жду вопросов и комментариев. Так же хотелось бы услышать предложения по улучшению алгоритма скрипта.
P.S. В коде намеренно допущена ошибка (а может и несколько ошибок – не помню), которые не позволяют использовать скрипт на полную катушку.
P.S. 2 Пробую пробиться на хабр
P.S. 3 Не пускают
No comments:
Post a Comment