Перейти к содержимому


Фотография
- - - - -

Парсинг на Python-е


  • Пожалуйста, авторизуйтесь, чтобы ответить
7 ответов в этой теме

#1 DarkTwin

DarkTwin

    Пернатый пЫнгвЫн

  • True Members
  • PipPipPipPipPip
  • 3 227 сообщений
293
Очень хороший
  • Пол:Мужчина

Опубликовано 14 Май 2013 - 08:33

Может кто ликбез провести?

На примере скажем сайта погоды.
http://rp5.ru/Weathe...ersburg,_Russia

import urllib
import lxml.html

page = urllib.urlopen('http://rp5.ru/Weather_in_Saint_Petersburg,_Russia/')
data = lxml.html.document_fromstring(page.read())
temperature = data.xpath('//span[@class="otstup"]/text()')

print(temperature)

я понимаю что делаю что то не так.
хотя бы то что /text() возвращает то что внутри тега, а температура там сразу за ним

<div class="t_0" style="display: inline;">
<b>
+
<span class="otstup"></span>
16
</b>
</div>

а вообще мне бы разобрать на кусочки нечто такое как во вложении.

Вложенные файлы

  • Вложенный файл  test.html   23,07 КБ   2 Скачано

  • 0

"Люди забыли эту истину, - сказал Лис, - но ты не забывай: ты навсегда в ответе за всех, кого приручил..."

Антуан де Сент-Экзюпери. Маленький принц


#2 Float

Float

    Super True Member

  • True Members
  • PipPipPipPipPip
  • 918 сообщений
23
Обычный

Опубликовано 14 Май 2013 - 10:01

А так?
data.xpath('//span[@class="otstup"]/following-sibling::text()')
  • 0

P.S. Учитывая особенности этого форума хочу добавить, что дети из серии "даю, 100, ну ладно 150" восприниматься всерьез не будут.

ты такой глупенький, что это уже даже не смешно


#3 DarkTwin

DarkTwin

    Пернатый пЫнгвЫн

  • True Members
  • PipPipPipPipPip
  • 3 227 сообщений
293
Очень хороший
  • Пол:Мужчина

Опубликовано 14 Май 2013 - 12:10

Пробовал.
Возвращает так же пусто.
import urllib
import lxml.html

page = urllib.urlopen('http://rp5.ru/Weather_in_Saint_Petersburg,_Russia/')
data = lxml.html.document_fromstring(page.read())
temperature = data.xpath('//span[@class="otstup"]/following-sibling::text()')

print(temperature)

C:\Python27\python.exe G:/damp/Dropbox/python/lxml/main.py
[]

Process finished with exit code 0



так
http://rp5.ru/Weathe...ersburg,_Russia/не нужна


Продолжение вопроса.


temperature = data.xpath('//div[t_0]/b/span[@class="otstup"]/following-sibling::text()')

как вот такое добавить
Это для вывода только цельсия.
  • 0

"Люди забыли эту истину, - сказал Лис, - но ты не забывай: ты навсегда в ответе за всех, кого приручил..."

Антуан де Сент-Экзюпери. Маленький принц


#4 Yarra

Yarra

    Псих ненормальный

  • Moderators
  • PipPipPipPipPip
  • 13 162 сообщений
319
Очень хороший
  • Город:Степка 8)

Опубликовано 14 Май 2013 - 13:07

решение:

temperature = data.xpath('//div[@class="t_0"]//span[@class="otstup"]/following-sibling::text()')

Странно, форум почему-то скобку переносит. во всяком случае у меня. ну да ладно.
  • 0

Люди должны умереть
Убью лошадь, за каплю никотина


#5 DarkTwin

DarkTwin

    Пернатый пЫнгвЫн

  • True Members
  • PipPipPipPipPip
  • 3 227 сообщений
293
Очень хороший
  • Пол:Мужчина

Опубликовано 17 Май 2013 - 14:16

На счет усложнения задачи.

Как правильно парсить таблицы ?
Пример в первом сообщении.


Как отдельные поля вывести ясно, а вот так что бы строки, да еще и так что мне нужны без нулевой стоимости и с разделением на кому принадлежит запись (номер абонента)

Малая часть того что нужно
# -*- coding: utf-8 -*-
__author__ = 'DarkTwin'
import urllib
import lxml.html
import time

start = time.time()

page = urllib.urlopen('test.html')
pageWritten = page.read()
pageReady = pageWritten.decode('utf-8')
PR = lxml.html.document_fromstring(pageReady)
data = PR.xpath('//td[@class="s13"]/text()')
cost = PR.xpath('//td[@class="s15"]/text()')
if len(data) == len(cost):
    for i in (i for i,x in enumerate(cost) if x != '0.00'):
        print data[i], cost[i]

    print u'Всего значений-', len(cost), u'из них без стоимости-', \
        cost.count('0.00'), u'интересующух строк-', len(cost)-cost.count('0.00')
else:
    print 'error'

finish = time.time()
print (finish - start)

  • 0

"Люди забыли эту истину, - сказал Лис, - но ты не забывай: ты навсегда в ответе за всех, кого приручил..."

Антуан де Сент-Экзюпери. Маленький принц


#6 DarkTwin

DarkTwin

    Пернатый пЫнгвЫн

  • True Members
  • PipPipPipPipPip
  • 3 227 сообщений
293
Очень хороший
  • Пол:Мужчина

Опубликовано 20 Май 2013 - 16:36

продолжаем страдать херней.

# -*- coding: utf-8 -*-
__author__ = 'DarkTwin'
import urllib
import lxml.html
import time

start = time.time()

page = urllib.urlopen('test.html')
pageWritten = page.read()
pageReady = pageWritten.decode('utf-8')
PR = lxml.html.document_fromstring(pageReady)

ab_name = PR.xpath('//td[@class="s3"]/text()')
data = PR.xpath('//td[@class="s13"]/text()')
dop = PR.xpath('//td[@class="s14"]/text()')
cost = PR.xpath('//td[@class="s15"]/text()')

time_val = dop[0:len(dop):6]
ab_namber = dop[1:len(dop):6]
time_cost = dop[2:len(dop):6]
type_of_service = dop[4:len(dop):6]

ab_name = [v for i,v in enumerate(ab_name) if v not in ab_name[:i]]

type_of_service = ['1' if x == u'Исходящие местные вызовы' else '1' if x == u'Исходящие междугородные вызовы' else '2' if x == u'Входящие вызовы' \
    else 'S' if x == u'Входящие SMS-сообщения' else 'S' if x == u'Исходящие SMS-сообщения' else 'S' if x == u'SMS:Входящие'\
    else 'S' if x == u'SMS:Исходящие' else '1' if x == u'Входящая связь' else 'M' if x == u'Исходящие MMS-сообщения'\
    else 'G' if x == u'Мобильный Интернет (пакетная передача данных)' else 'G' if x == u'Пакетная передача данных'\
    else 'M' if x == u'Входящие MMS-сообщения' else 'T' if x == u'Технологические вызовы' \
    else '3' if x == u'Входящие вызовы, автоматически переадресованные с доп. городского номера на федеральный номер' \
    else 'S' if x == u'Услуги на коротких номерах (исходящие SMS-сообщения)' else 'U' if x == u'Услуги  на коротких номерах (USSD)' \
    else '1' if x == u'Исходящая связь' else '1' if x == u'Исходящие международные вызовы'\
    else x for x in type_of_service]


if len(data) == len(cost):
    for i in (i for i,x in enumerate(cost) if x != '0.00'):
        print data[i], time_val[i], ab_namber[i],  time_cost[i], type_of_service[i],  cost[i]

    print u'Всего значений-', len(cost), u'из них без стоимости-', \
        cost.count('0.00'), u'интересующух строк-', len(cost)-cost.count('0.00')
else:
    print 'error'

for i in (i for i,x in enumerate(ab_name)):
        print ab_name[i]

finish = time.time()
print (finish - start)

в результате получаем 555 строк вида
01.04.13 20:00:49 0 0 U 30.00
03.04.13 11:35:37 9147563100 0 M 6.00
05.04.13 07:38:55 INTERNET 100 G 0.34
05.04.13 20:47:14 9658011033 0 M 6.00

Все бы хорошо, но надо разделить это все по именам абонентов.
То что обзывается ab_name.

Дайте толчок мысли.
  • 0

"Люди забыли эту истину, - сказал Лис, - но ты не забывай: ты навсегда в ответе за всех, кого приручил..."

Антуан де Сент-Экзюпери. Маленький принц


#7 DarkTwin

DarkTwin

    Пернатый пЫнгвЫн

  • True Members
  • PipPipPipPipPip
  • 3 227 сообщений
293
Очень хороший
  • Пол:Мужчина

Опубликовано 27 Июнь 2013 - 06:41

Как то так
# -*- coding: utf-8 -*-

from lxml import etree
from pyquery import PyQuery
from re import search
from time import gmtime, strftime, time
from os import path, curdir, makedirs
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

#отмечаем время начала работы скрипта
start = time()

p_name = strftime("%d_%m_%Y", gmtime())

if path.exists(p_name):
    if path.isdir(p_name):
        print('В директории имеется каталог с таким именем')
else:
    makedirs(p_name)
    print('Папка создана')

keys = [
    'перечисляем номера абонентов',
    ]

values = [
    u' перечисляем имена абонентов',
]
n2names = dict(zip(keys, values))


def pyqs(seq):
    return [PyQuery(i) for i in seq]


def fetch_number(s):
    return search('\+(\d+)', s).group(1)


result = {}
tree = etree.HTML(file('test.html', 'rb').read(), parser=etree.HTMLParser(encoding='utf-8'))
dom = PyQuery(tree, parser='html')

number = None

for tbl in pyqs(dom('table')):  # проходимся по всем элементам 'таблица'
    for tr in pyqs(tbl.find('tr')):  # находим строки в таблицах
        row = []
        for td in pyqs(tr.find('td')):  # находим ячейки в строках таблицы
            td_class = td.attr.class_
            if td_class in ['s13', 's14', 's15']:  # будем работать с тем что имеет td class=s13 итд
                row.append(td.text())
                continue
            if td_class == 's3':  # находим заголовок таблицы в котором номер абанета
                number = fetch_number(td.text())  # отправляем в функцию для выделения номера из строки
                if not result.has_key(number):  # если раньше номера не было — создаем новых ключ в словаре
                    result[number] = []
        if len(row) != 8:  # мы нашли нужную нам строчку
            continue
        row[7] = float(row[7])  # стоимость вызова переводим в число
        if row[7]:
            result[number].append(row)

for number, data in result.iteritems():
    f = open(path.join(path.abspath(curdir), p_name, number)+'.txt', 'w+')
    f.write(number+'\t'+n2names.get(number, '')+'\n\n')
    f.write('Дата\t\Времяt\tНомер/Имя\tНаименование услуги\tДлительность\tСтоимость\n')
    for row in data:
        s = ('%s\t%s\t%s\t%s\t%s\t%.2f' % (row[0], row[1], row[2], row[5], row[3], row[7]))
        f.write(s+'\n')
    f.write('\nИтого: %.2f' % sum(row[7] for row in data))
    f.close()

finish = time()
print (finish - start)


Следующий этап проще.
Разослать это все по почте кому надо :)
  • 0

"Люди забыли эту истину, - сказал Лис, - но ты не забывай: ты навсегда в ответе за всех, кого приручил..."

Антуан де Сент-Экзюпери. Маленький принц


#8 DarkTwin

DarkTwin

    Пернатый пЫнгвЫн

  • True Members
  • PipPipPipPipPip
  • 3 227 сообщений
293
Очень хороший
  • Пол:Мужчина

Опубликовано 30 Сентябрь 2013 - 19:56

Пожалуйста, ближе к делу. Изображение

В бан умника.
  • 0

"Люди забыли эту истину, - сказал Лис, - но ты не забывай: ты навсегда в ответе за всех, кого приручил..."

Антуан де Сент-Экзюпери. Маленький принц



Посетителей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных пользователей