= Краулеры = {{{#!python >>> import urllib.request >>> x = urllib.request.urlopen("http://yandex.ru") >>> text = x.read() >>> text[:100] b'<!DOCTYPE html><html class="i-ua_js_no i-ua_css_standart i-ua_browser_" lang="ru"><head xmlns:og="ht' }}} {{{#!python >>> x = urllib.request.urlopen("http://yandex.ru/yandsearch?text=hello") >>> text = x.read() >>> text[:100] b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtm' }}} {{{#!python >>> x = urllib.request.urlopen("http://yandex.ru/yandsearch?text=hello") >>> yatext = x.read() >>> rutext = yatext.decode("utf-8") }}} {{{#!python >>> import re >>> re.sub('<[^>]*>', '', rutext) '\n\n\n\n \n \n \n \n \n \n \n \n \n -->\n\n \n function Focus() {\n document.getElementById("rep").focus();\n }\n \n\n \n function ShowText() {\n var d = document.getElementById("id_captcha_text");\n d.style.display = (d.style.display == \'block\') ? \'\' : \'block\';\n }\n \n Ой!\n\n\n\n\n\n \n \n \n \n \n\n \n \n \n \n \n \n \n\n \n\n \n \n \n \n \n \n\n \n ой...\n \n\n \n \n \n \n \n \n \n \n\n \n\n \n \n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n\n \n\n \n \n \nНам очень жаль, но запросы, поступившие с вашего IP-адреса, похожи на автоматические.\nПо этой причине мы вынуждены временно заблокировать доступ к поиску.\nЧтобы продолжить поиск, пожалуйста, введите символы с картинки в поле ввода и нажмите «Отправить».\n\n \n \n \n \n\n \n \n \n \n \n \n \n \n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n Показать другую картинку\n \n \n \n \n \n \n \n \n В вашем браузере отключены файлы cookies. Яндекс не сможет запомнить вас и правильно идентифицировать в дальнейшем. Чтобы включить cookies, воспользуйтесь советами на странице нашей Помощи. \n \n \n \n \n\n \n \n \n\nПочему так случилось?\n\n\n Возможно, автоматические запросы принадлежат не вам, а другому пользователю, выходящему в сеть с одного с вами IP-адреса.\n Вам необходимо один раз ввести символы в форму, после чего мы запомним вас и сможем отличать от других пользователей, выходящих с данного IP.\n В этом случае страница с капчей не будет беспокоить вас довольно долго.\n Возможно, в вашем браузере установлены дополнения, которые могут задавать автоматические запросы к поиску. В этом случае рекомендуем вам отключить их.\n Также возможно, что ваш компьютер заражен вирусной программой, использующей его для сбора информации.\n Может быть, вам стоит проверить систему на наличие вирусов, например, антивирусной утилитой CureIt от «Dr.Web». \n Если у вас возникли проблемы или вы хотите задать вопрос нашей службе поддержки, пожалуйста, воспользуйтесь\n формой обратной связи.\n \n\n\n\n \n Если автоматические запросы действительно поступают с вашего компьютера, и вы об этом знаете (например, вам по роду деятельности необходимо отправлять Яндексу\n подобные запросы), рекомендуем воспользоваться специально разработанным для этих целей сервисом\n Яндекс.XML.\n\n\n\n \n \n\n \n\n \n\n \n \n \n \n \n \n \n \n \n \n\n \n\n \n \n Обратная связь\n \n \n\n \n \n © 1997—2014 «Яндекс»\n \n \n\n \n \n \n \n \n \n \n(function (d, w, c) { (w[c] = w[c] || []).push(function() { try { w.yaCounter10630330 = new Ya.Metrika({id:10630330, webvisor:true, clickmap:true, trackLinks:true, accurateTrackBounce:true, ut:"noindex"}); } catch(e) { } }); var n = d.getElementsByTagName("script")[0], s = d.createElement("script"), f = function () { n.parentNode.insertBefore(s, n); }; s.type = "text/javascript"; s.async = true; s.src = (d.location.protocol == "https:" ? "https:" : "http:") + "//mc.yandex.ru/metrika/watch.js"; if (w.opera == "[object Opera]") { d.addEventListener("DOMContentLoaded", f, false); } else { f(); } })(document, window, "yandex_metrika_callbacks");\n\n \n\n\n\n' }}} {{{#!python >>> noscript = re.sub('<script[^<]*</script>', '', rutext) >>> clean = re.sub('<[^>]*>', '', noscript) >>> re.sub('\s+', ' ', clean) ' --> Ой! ой... Нам очень жаль, но запросы, поступившие с вашего IP-адреса, похожи на автоматические. По этой причине мы вынуждены временно заблокировать доступ к поиску. Чтобы продолжить поиск, пожалуйста, введите символы с картинки в поле ввода и нажмите «Отправить». Показать другую картинку В вашем браузере отключены файлы cookies. Яндекс не сможет запомнить вас и правильно идентифицировать в дальнейшем. Чтобы включить cookies, воспользуйтесь советами на странице нашей Помощи. Почему так случилось? Возможно, автоматические запросы принадлежат не вам, а другому пользователю, выходящему в сеть с одного с вами IP-адреса. Вам необходимо один раз ввести символы в форму, после чего мы запомним вас и сможем отличать от других пользователей, выходящих с данного IP. В этом случае страница с капчей не будет беспокоить вас довольно долго. Возможно, в вашем браузере установлены дополнения, которые могут задавать автоматические запросы к поиску. В этом случае рекомендуем вам отключить их. Также возможно, что ваш компьютер заражен вирусной программой, использующей его для сбора информации. Может быть, вам стоит проверить систему на наличие вирусов, например, антивирусной утилитой CureIt от «Dr.Web». Если у вас возникли проблемы или вы хотите задать вопрос нашей службе поддержки, пожалуйста, воспользуйтесь формой обратной связи. Если автоматические запросы действительно поступают с вашего компьютера, и вы об этом знаете (например, вам по роду деятельности необходимо отправлять Яндексу подобные запросы), рекомендуем воспользоваться специально разработанным для этих целей сервисом Яндекс.XML. Обратная связь © 1997—2014 «Яндекс» ' }}} == robots.txt == {{{#!python >>> import urllib.robotparser >>> p = urllib.robotparser.RobotFileParser('http://yandex.ru') >>> p.can_fetch('urllib', 'http://yandex.ru/yandsearch?text=hello') True }}} {{{#!python >>> p = urllib.robotparser.RobotFileParser('http://yandex.ru/robots.txt') >>> p.can_fetch('urllib', 'http://yandex.ru/yandsearch?text=hello') True }}} {{{#!python >>> p = urllib.robotparser.RobotFileParser('http://yandex.ru/robots.txt') >>> p.read() >>> p.can_fetch('urllib', 'http://yandex.ru/yandsearch?text=hello') False >>> p.can_fetch('urllib', 'http://yandex.ru/yac2014/') True }}} == Главный цикл == {{{#!python urls = ['http://newsru.com'] for url in urls: # fetch page # find all urls in page # avoid uninteresting links # avoid links we've already seen # add new urls to our list }}} {{{#!python from urllib.request import urlopen import re urls = ['http://newsru.com'] for url in urls: print(url) # fetch page file = urlopen(url) text = file.read() # find all urls in page # avoid uninteresting links # avoid links we've already seen # add new urls to our list }}} {{{#!python from urllib.request import urlopen import re urls = ['http://newsru.com'] for url in urls: print(url) # fetch page file = urlopen(url) text = file.read() if 'charset' in file.headers['content-type']: charset, = re.findall('charset=(.*)', file.headers['content-type']) elif b'charset=cp1251' in text: charset = 'windows-1251' elif b'charset=windows-1251' in text: charset = 'windows-1251' elif b'charset=utf-8' in text: charset = 'utf-8' text = text.decode(charset) # find all urls in page # avoid uninteresting links # avoid links we've already seen # add new urls to our list }}} {{{#!python from urllib.request import urlopen import re domain = 'http://newsru.com' urls = ['http://newsru.com'] for url in urls: print(url) # fetch page file = urlopen(url) text = file.read() if 'charset' in file.headers['content-type']: charset, = re.findall('charset=(.*)', file.headers['content-type']) elif b'charset=cp1251' in text: charset = 'windows-1251' elif b'charset=windows-1251' in text: charset = 'windows-1251' elif b'charset=utf-8' in text: charset = 'utf-8' text = text.decode(charset) # find all urls in page for link in re.findall('href=["\']([^"\']*)["\']', text): if link.startswith("/"): link = domain + link # avoid uninteresting links if link.startswith("http://"): continue if link.startswith("https://"): continue # avoid links we've already seen if link in urls: continue # add new urls to our list urls.append(link) }}} {{{#!python from urllib.request import urlopen from urllib.robotparser import RobotFileParser import re domain = 'http://newsru.com' urls = ['http://newsru.com'] robots = RobotFileParser(domain + '/robots.txt') robots.read() for url in urls: print(url) # fetch page # if we may if not robots.can_fetch('urllib', url): print('denied') continue file = urlopen(url) text = file.read() if 'charset' in file.headers['content-type']: charset, = re.findall('charset=(.*)', file.headers['content-type']) elif b'charset=cp1251' in text: charset = 'windows-1251' elif b'charset=windows-1251' in text: charset = 'windows-1251' elif b'charset=utf-8' in text: charset = 'utf-8' text = text.decode(charset) # find all urls in page for link in re.findall('href=["\']([^"\']*)["\']', text): # avoid uninteresting links if link.startswith("http://"): continue if link.startswith("https://"): continue # but still parse the interesting ones if link.startswith("/"): link = domain + link if link.startswith('#'): continue # avoid links we've already seen if link in urls: continue # add new urls to our list urls.append(link) }}} {{{#!python from urllib.request import urlopen from urllib.robotparser import RobotFileParser import re domain = 'http://newsru.com' urls = ['http://newsru.com'] def fetch_page(url): file = urlopen(url) text = file.read() charset = detect_charset(file, text) retun text.decode(charset) def detect_charset(file, text): if 'charset' in file.headers['content-type']: return re.findall('charset=(.*)', file.headers['content-type'])[0] elif b'charset=cp1251' in text: return 'windows-1251' elif b'charset=windows-1251' in text: return 'windows-1251' elif b'charset=utf-8' in text: return 'utf-8' def add_new_links(text, urls): for link in re.findall('href=["\']([^"\']*)["\']', text): if is_boring_link(link): continue link = normalize_link(link) if link in urls: continue urls.append(link) def normalize_link(link): if link.startswith("/"): return domain + link elif '://' in link: return link # else ... def is_boring_link(link): if link.startswith("http://"): return True if link.startswith("https://"): return True if link.startswith('#'): return True robots = RobotFileParser(domain + '/robots.txt') robots.read() for url in urls: if not robots.can_fetch('urllib', url): print(url) text = fetch_page(url) add_new_links(text, urls) else: print(url, 'denied') }}} ## vim: set et sw=4 ts=4 sts=4: