В предыдущем посте я опубликовал сообщения из консоли при успешном запуске dmoz. Здесь мы добавим к этому работающему коду вставки от randomproxy (scrapy middleware), получим ошибки парсинга строк в модуле... и решим не реанимировать модуль, а посмотреть другие.
Первоисточники и ссылки¶
randomproxy.py GitHub
re.match(pattern, string, flags=0)
7.2.5. Match Objects Python 2.6
Crawling Scrapy Tutorial
re.match(pattern, string, flags=0)
7.2.5. Match Objects Python 2.6
Crawling Scrapy Tutorial
Как и написано в руководстве, я скопировал randomproxy.py в dirbot, и добавил строки в файл settings.py¶
In [3]:
!chcp 65001
!dir C:\Users\kiss\Documents\GitHub\dirbot_se1\dirbot
In [4]:
%load 'C:\\Users\\kiss\\Documents\\GitHub\\dirbot_se1\\dirbot\\settings.py'
In []:
# Scrapy settings for dirbot project
SPIDER_MODULES = ['dirbot.spiders']
NEWSPIDER_MODULE = 'dirbot.spiders'
DEFAULT_ITEM_CLASS = 'dirbot.items.Website'
ITEM_PIPELINES = ['dirbot.pipelines.FilterWordsPipeline']
# Ниже все, что добавлено к оригинальному файлу
# Retry many times since proxies often fail
RETRY_TIMES = 10
# Retry on most error codes since proxies fail for different reasons
RETRY_HTTP_CODES = [500, 503, 504, 400, 403, 404, 408]
DOWNLOADER_MIDDLEWARES = {
'scrapy.contrib.downloadermiddleware.retry.RetryMiddleware': 90,
# Fix path to this module
'dirbot.randomproxy.RandomProxy': 100,
'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': 110,
}
# Proxy list containing entries like
# http://host1:port
# http://username:password@host2:port
# http://host3:port
# ...
PROXY_LIST = 'dirbot/list.txt'
In [5]:
%load 'C:\\Users\\kiss\\Documents\\GitHub\\dirbot_se1\\dirbot\\randomproxy.py'
In []:
import re
import random
import base64
from scrapy import log
# debugger
import pdb
class RandomProxy(object):
def __init__(self, settings):
self.proxy_list = settings.get('PROXY_LIST')
fin = open(self.proxy_list)
self.proxies = {}
for line in fin.readlines():
parts = re.match('(\w+://)(\w+:\w+@)?(.+)', line)
pdb.set_trace()
# Cut trailing @
if parts[1]: # line 16
parts[1] = parts[1][:-1]
self.proxies[parts[0] + parts[2]] = parts[1]
fin.close()
@classmethod
def from_crawler(cls, crawler): # line 25
return cls(crawler.settings)
def process_request(self, request, spider):
# Don't overwrite with a random one (server-side state for IP)
if 'proxy' in request.meta:
return
proxy_address = random.choice(self.proxies.keys())
proxy_user_pass = self.proxies[proxy_address]
request.meta['proxy'] = proxy_address
if proxy_user_pass:
basic_auth = 'Basic ' + base64.encodestring(proxy_user_pass)
request.headers['Proxy-Authorization'] = basic_auth
def process_exception(self, request, exception, spider):
proxy = request.meta['proxy']
log.msg('Removing failed proxy <%s>, %d proxies left' % (
proxy, len(self.proxies)))
try:
del self.proxies[proxy]
except ValueError:
pass
А в консоли выскочили ошибки как раз в файле randomproxy.py¶
In []:
C:\Users\kiss\Documents\GitHub\dirbot_se1>scrapy crawl dmoz
2014-04-23 19:16:40+0400 [scrapy] INFO: Scrapy 0.20.1 started (bot: scrapybot)
2014-04-23 19:16:40+0400 [scrapy] DEBUG: Optional features available: ssl, http11, boto, django
2014-04-23 19:16:40+0400 [scrapy] DEBUG: Overridden settings: {'DEFAULT_ITEM_CLASS': 'dirbot.items.Website', 'NEWSPIDER_MODULE': 'di
rbot.spiders', 'SPIDER_MODULES': ['dirbot.spiders'], 'RETRY_TIMES': 10, 'RETRY_HTTP_CODES': [500, 503, 504, 400, 403, 404, 408]}
2014-04-23 19:16:42+0400 [scrapy] DEBUG: Enabled extensions: LogStats, TelnetConsole, CloseSpider, WebService, CoreStats, SpiderStat
e
Traceback (most recent call last):
File "C:\Users\kiss\Anaconda\lib\runpy.py", line 162, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "C:\Users\kiss\Anaconda\lib\runpy.py", line 72, in _run_code
exec code in run_globals
.................
.................
File "C:\Users\kiss\Anaconda\lib\site-packages\scrapy\middleware.py", line 50, in from_crawler
return cls.from_settings(crawler.settings, crawler)
File "C:\Users\kiss\Anaconda\lib\site-packages\scrapy\middleware.py", line 31, in from_settings
mw = mwcls.from_crawler(crawler)
File "dirbot\randomproxy.py", line 25, in from_crawler
return cls(crawler.settings)
File "dirbot\randomproxy.py", line 16, in __init__
if parts[1]:
TypeError: '_sre.SRE_Match' object has no attribute '__getitem__'
В сроке 25 - это строка после "@classmethod", а строка 16 - это условие "if parts[1]:" Начнем с ошибки
Оказывается, что re.math выдает объект, а не список. Для того, чтобы обратится к элементу объекта нужно пользоваться свойством parts.group(0), а не parts[0]
Зачем автору понадобилось загонять список прокси в словарь? Не понятно... и подозрительно. Пока (после этого) не хочется тратить время на раскопки..., потому оставим здесь примеры с groups() и закончим этот пост. Надо посмотреть другие пакеты рабты с прокси, а уж потом решить, стоит ли реанимировать этот.
Зачем автору понадобилось загонять список прокси в словарь? Не понятно... и подозрительно. Пока (после этого) не хочется тратить время на раскопки..., потому оставим здесь примеры с groups() и закончим этот пост. Надо посмотреть другие пакеты рабты с прокси, а уж потом решить, стоит ли реанимировать этот.
In [7]:
import re
line='http://94.180.118.34:8080\n'
In [8]:
parts = re.match('(\w+://)(\w+:\w+@)?(.+)', line)
In [9]:
print parts
In [11]:
parts = re.split('(\w+://)(\w+:\w+@)?(.+)', line)
parts
Out[11]:
In [12]:
parts[1] = parts[1][:-1]
In [14]:
parts[1]
Out[14]:
In [16]:
p02=parts[0] + parts[2]
In [17]:
#Example from 2.6 version of Python
m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
In [18]:
m.group(0)
Out[18]:
In [19]:
m
Out[19]:
In [20]:
parts.group(0)
In [21]:
parts = re.match('(\w+://)(\w+:\w+@)?(.+)', line)
In [22]:
parts.group(0)
Out[22]:
In [27]:
parts.group(1),parts.group(2),parts.group(3)
Out[27]:
Посты чуть ниже также могут вас заинтересовать
Несколько приемов, которые показались необычными:
ОтветитьУдалить1. Задал константу PROXY_LIST = 'dirbot/list.txt' в файле settings.py
2. Затем использовал эту константу в другом модуле
class RandomProxy(object):
def __init__(self, settings):
self.proxy_list = settings.get('PROXY_LIST')
fin = open(self.proxy_list)