2016-12-08 4 views
0

У меня проблема с моим кодом. Есть два файла - скребок и парсер. В них очень мало импорта, но я все еще получаю ошибку импорта.Невозможно импортировать имя <name_of_function> - не видно круговых вводок

from parser import parse_price

ImportError: cannot import name parse_price

Я предполагаю, что это должно быть вызвано круговым импортом, но я не могу найти ...

Я бега scraper.py через PyCharm. (есть линия print get_price(...)

У вас проблема?

parser.py:

# -*- coding: utf-8 -*- 

""" 
Parse prices strings in various formats 

e.g: $1,997.00 

""" 
import decimal 
from exceptions import Exception 
import re 

_CURRENCIES = u'eur;czk;sk;kč'.split(';') 
_SIGNS = u'$;€;£'.split(';') 

CURRENCY_STRINGS = [x for x in _CURRENCIES]+[x.capitalize() for x in _CURRENCIES]+[x.upper() for x in _CURRENCIES] 
CURRENCY_SIGNS = _SIGNS 

REMOVE_STRINGS = CURRENCY_STRINGS + CURRENCY_SIGNS 


class PriceParseException(Exception): 
    pass 

def parse_price(text): 
    text = text.strip() 
    # try: 
    non_decimal = re.compile(r'[^\d,.]+') 
    text = non_decimal.sub('', text).replace(',','.') 
    if not len([x for x in text if x in '123456789']): 
     raise Exception 
    price = decimal.Decimal(text.strip()) 
    # except: 
    #  raise 
    #  raise PriceParseException() 

    return price 



from tld import get_tld,update_tld_names #TODO: from tld.utils import update_tld_names; update_tld_names() + TABULKU/MODEL TLD_NAMES 

def parse_site(url): 
    try: 
     return get_tld(url) 
    except: 
     return None 

scraper.py:

import requests 
from django.utils.datetime_safe import datetime 
from lxml import etree 
from exceptions import Exception 

class ScanFailedException(Exception): 
    pass 

def _load_root(url): 
    r = requests.get(url) 
    r.encoding = 'utf-8' 
    html = r.content 
    return etree.fromstring(html, etree.HTMLParser()) 

def _get_price(url,xpath): 
    root = _load_root(url) 
    try: 
     return root.xpath(xpath+'/text()')[0] 
    except: 
     raise ScanFailedException() 

def get_price(url,xpath): 
    response = {} 
    root = _load_root(url) 
    try: 
     price = ''.join([x for x in root.xpath(xpath+'/text()') if any(y in x for y in '123456789')]) 
    except: 
     response['error'] = 'ScanFailedException' 
     return response 

    try: 
     from parser import parse_price #HERE IS THE PROBLEM 
     decimal_price = parse_price(price) 
     response['price']=str(decimal_price) 
    except: 
     raise 
     response['error'] = 'PriceParseException' 
     return response 
    return response 



print get_price('some_url', 
      '//strong[@class="product-detail-price"]') 

def scrape_product(product): 
    from main_app.models import Scan 
    for occ in product.occurences.all(): 
     try: 
      from parser import parse_price 
      url = occ.url 
      xpath = occ.xpath 
      raw_price = _get_price(url,xpath) 

      price = parse_price(raw_price) 
      Scan.objects.create(occurence=occ, datetime=datetime.now(), price=price) 
     except: 
      """Create invalid scan""" 
      Scan.objects.create(occurence=occ,datetime=datetime.now(),price=None,valid=False) 
+0

Возвращаясь объект, содержащий информацию об ошибке не Pythonic, просто дайте исключению пузырь до места, где вы сможете справиться с ним должным образом. Кроме того, это не сработает, поскольку вы «поднимите», прежде чем у него появится шанс «вернуться». – jonrsharpe

+0

@ Milano Какая ОС вы используете? Вы пытались изменить имя файла на другое, кроме 'parser.py'? – ettanany

ответ

1

Вы не должны вызывать файл parser.py, поскольку parser является существующий модуль в Python.

Прочитайте следующее, чтобы лучше понять:

>>> import parser 
>>> 
>>> dir(parser) 
['ASTType', 'ParserError', 'STType', '__copyright__', '__doc__', '__name__', '__package__', '__version__', '_pickler', 'ast2list', 'ast2tuple', 'compileast', 'compilest', 'expr', 'isexpr', 'issuite', 'sequence2ast', 'sequence2st', 'st2list', 'st2tuple', 'suite', 'tuple2ast', 'tuple2st'] 
>>> 
>>> 'parse_price' in dir(parser) 
False 

Вы видите, модуль Python parser не parse_price, то:

>>> from parser import parse_price 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: cannot import name parse_price 
+1

Хотя хороший совет, который не вызвал бы эту проблему, Python будет использовать локальный 'parser' * before * стандартную библиотеку. – jonrsharpe

+0

@jonrsharpe вы можете попробовать это на своей машине и сообщить мне, какой результат вы получаете. Я знал, что вы упомянули, но я удивлен, что это не так в моей машине для окон. Я создал 'parser.py' и' parser_2.py' в той же папке, и когда я импортирую parser_2, он отлично работает, но когда я импортирую 'parser', вместо этого импортируется модуль python! – ettanany

+0

Проверено на моей машине Ubuntu, и все работает отлично, и, как ожидалось, 'import parser' импортирует локальный модуль, а не Python. – ettanany