Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 6, 2013 09:47:04

Mariarchy
Зарегистрирован: 2013-02-06
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг со scrapy

Разбираюсь с работой парсинга на scrapy, пробовал примеры из документации - идут, как только столкнулся с русскоязычным примером: http://gis-lab.info/qa/scrapy.html в файл вывода (без разницы json csv) выводится все в Unicode:{“name”: ["\u0418\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u…..
Чтобы не ждать долго, парсер всего сайта сузил до 1 страницы
Spider:

# -*- coding: utf-8 -*-
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.contrib.loader.processor import TakeFirst
from scrapy.contrib.loader import XPathItemLoader
from scrapy.selector import HtmlXPathSelector
from orphanage.items import OrphanageItem
 
 
class OrphanSpider(CrawlSpider):
    name = "detskiedomiki"
    allowed_domains = ["www.detskiedomiki.ru"]
    start_urls = ["http://www.detskiedomiki.ru/guide/child/"]
 
    rules = (
        #Rule(SgmlLinkExtractor(allow=('act=home_reg', 'act=home_zone')), follow=True),
        Rule(SgmlLinkExtractor(allow=('http://detskiedomiki.ru/?act=home_more&id=6278&z_id=3&part_id=65')), callback='parse_item'),
    )
 
    def parse_item(self, response):
        hxs = HtmlXPathSelector(response)
        l = OrphanLoader(OrphanageItem(), hxs)
 
        #
        l.add_xpath('id', "//td[text()='%s']/following-sibling::td/text()" % u"Рег. номер:")
        l.add_xpath('region', "//td[text()='%s']/following-sibling::td/text()" % u"Регион:")
        l.add_xpath('district', "//td[text()='%s']/following-sibling::td/text()" % u"Район:")
        l.add_xpath('type', "//td[text()='%s']/following-sibling::td/text()" % u"Тип учреждения:")
        l.add_xpath('name', "//td[text()='%s']/following-sibling::td/strong/text()" % u"Название:")
        return l.load_item()
[b]pipeline[/b]:
import json
class FasttorrentPipeline(object):
    def __init__(self):
        self.file = open('items.txt', 'wb')
    def process_item(self, item, spider):
        line = json.dumps(dict(item)) + "\n"
        self.file.write(line)
        
        return item
Вызываю: scrapy crawl domiki

Как вывести название нормально?

Отредактировано FishHook (Фев. 6, 2013 10:07:58)

Офлайн

#2 Фев. 6, 2013 10:08:59

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

парсинг со scrapy

Mariarchy,

[code python][/code]



Офлайн

#3 Фев. 6, 2013 11:22:20

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

парсинг со scrapy

Mariarchy
Как вывести название нормально?
Нормально - это как? Если речь идет о том, что name - не строка, а список, то нужно посмотреть код OrphanLoader (кстати, импорта тоже не увидел).
Там должно быть
class OrphanLoader(ItemLoader):
    default_output_processor = TakeFirst()
    ...
или
class OrphanLoader(ItemLoader):
    name = TakeFirst()
    ...
Если речь о Юникоде:
json.dumps(..., ensure_ascii=False)

Офлайн

#4 Фев. 6, 2013 12:10:56

Mariarchy
Зарегистрирован: 2013-02-06
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг со scrapy

reclosedev
Спасибо, имелась в виду кодировка. Точно помню что пробовал это:

json.dumps(..., ensure_ascii=False)
и не получалось.
Сейчас попробовал по вашему совету еще раз - все заработало…
“нужно посмотреть код OrphanLoader (кстати, импорта тоже не увидел)” - щас буду читать/экспериментировать с ItemLoader

Офлайн

#5 Фев. 6, 2013 12:52:59

Mariarchy
Зарегистрирован: 2013-02-06
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг со scrapy

Все, понял, почему у меня не работало. Если писать self.file.write(line.encode('utf-8'))все хорошо, а если self.file.write(line) - ошибка UnicodeEncodeError “ascii”

Офлайн

#6 Фев. 6, 2013 14:05:09

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

парсинг со scrapy

Mariarchy
Все, понял, почему у меня не работало. Если писать self.file.write(line.encode('utf-8'))все хорошо, а если self.file.write(line) - ошибка UnicodeEncodeError “ascii”
Еще можно открывать файл с помощью codecs.open('items.txt', encoding='utf-8')
и писать в него Юникод.

Офлайн

#7 Июнь 19, 2013 10:24:54

Mariarchy
Зарегистрирован: 2013-02-06
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг со scrapy

Решил продолжить изучение парсинга со скрапи и вскоре наткнулся на новую неожиданную проблему.
Имеется сайт http://fast-torrent.ru/ для тренировки хочу стянуть рейтинг фильмов и названия скажем первых 10 страниц. (http://fast-torrent.ru/russian/2.html, http://fast-torrent.ru/russian/3.html….http://fast-torrent.ru/russian/11.html)
Запускаю парсер: он парсит только 2.html и 3.html, другие не парсит, даже если пишу в Rules только одну страницу > 3.
Ошибок нет, просто в cmd выходит строка Closing spider (не знаю, как тут правильнее выложить в code или в тексте)

class FastTor(CrawlSpider):
    name = 'FastTor1'
    allowed_domains = ['fast-torrent.ru']
    start_urls = ['http://fast-torrent.ru/russian/']
    rules = [Rule(SgmlLinkExtractor(allow=['/russian/4.html']), 'parse_torrent')]
    def parse_torrent(self, response):
        x = HtmlXPathSelector(response)
        i=0
        torrent = FasttorrentItem()
        torrent['name'] = x.select("//tr[@class='tr-type-video']/td[@colspan='3']/h2[1]/text()").extract()
        torrent['rating'] = x.select("//tr[@class='tr-type-video']/td[@colspan='3']/div/span/ul/li").extract()
        torrent['description']=['']
        name=torrent['name']
        rating=torrent['rating']
        print (len(name))
        description=torrent['description']
        p_name=re.compile('^(\()(\w)')
        p_rating=re.compile(r'([0-9]\.\d+)')
        while i < len(name):
            if p_name.findall(name[i]):
                del name[i]
            i=i+1
        i=0
        while i < len(rating):
            if p_rating.findall(rating[i]):
                rating[i]=p_rating.findall(rating[i])
                rating[i]=re.sub('[\[\]\'\']','',str(rating[i]))
                rating[i]=re.sub('[u]','',rating[i])
            else:
                rating[i]='0 '
            i=i+1
        i=0
        while i < len(rating):
            description.append(rating[i]+' '+name[i])
            i=i+1
        return torrent
Просто вообще вариантов нет никаких, кроме как с другой машины попробовать(

Офлайн

#8 Июнь 19, 2013 20:09:51

Mariarchy
Зарегистрирован: 2013-02-06
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг со scrapy

Проверил с другой машины, где интернет без прокси - та же фигня, почему-то страницы с нумерацией > 3 не обрабатываются.

Офлайн

#9 Июнь 20, 2013 12:53:53

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

парсинг со scrapy

Напишите в майл-лист скрапи, больше шансов, что получите ответ: http://groups.google.com/group/scrapy-users

Офлайн

#10 Июнь 20, 2013 13:14:57

Mariarchy
Зарегистрирован: 2013-02-06
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг со scrapy

спасибо, наверное, так и сделаю

P/S/ Чем посоветуете пользоваться для парсинга?

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version