LINUX.ORG.RU

Наколеночный скрипт Python

 , , ,


1

1

В продолжение прошлой темы, я, как любитель K&R C Book, накропал вот такой «наколеночный» говнокод,

чтобы парсить исходники из глав (сорцы внутри тега pre).

Прошу спецов по Питону его усовершенствовать, т.к. с Цирко-Змеем практически не знаком.

Код


#!/usr/bin/python
import sys
from bs4 import BeautifulSoup

 

soup = BeautifulSoup(open(sys.argv[1],'r'))
foutput = open(sys.argv[2],'w')
y = soup.find_all('pre') 
for a in y:
	z = a.string
	foutput.write(z)
★★★★★

Последнее исправление: Twissel (всего исправлений: 2)

use with, luke!

with open('mscore.dll','w') as f:
    do_dll_hell()
anonymous
()

Как-то так. Не проверял. Можно ещё лучше сделать, но мне дальше лень.

#!/usr/bin/python
import os
import sys
from bs4 import BeautifulSoup

if not len(sys.argv) == 3:
    print 'Usage: %s <input> <output>' %s sys.argv[0]
    exit(1)

in_file = sys.argv[1]
out_file = sys.argv[2]

if not os.path.exists(in_file):
    print 'File %s does not exists' % in_file 
    exit(1)

with open(in_file, 'r') as source:
    soup = BeautifulSoup(source)
    with open(out_file, 'w') as dest:
        for i in soup.find_all('pre'):
            dest.write(i.string)

Kilte ★★★★★
()
Ответ на: комментарий от Kilte

Спасибо, красиво!

Сейчас попробую.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Не понял. Всё работает теперь?

Вообще я слышал, что более pythonic-way — использовать метод format. Ну это уже сам решай. Как по-мне, старый стиль удобнее будет. Хотя для именованных плейсхолдеров предпочитаю использовать всё-таки format.

Kilte ★★★★★
()
Ответ на: комментарий от Kilte

Да, все отлично :-)

Не знаю для задачи такого размера, по-моему, это не имеет значения.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Не будет мучительно больно, если захочется добавить больше ключей.

PolarFox ★★★★★
()

НЕ ИСПОЛЬЗУЙ BeautifulSoup, используй html5lib.

#!/usr/bin/python
import sys
import html5lib

f = open(sys.argv[1],'r')
document = html5lib.parse(f, treebuilder="lxml")
contents = document.xpath('//pre/node()')
cheerfulboy
()
Ответ на: комментарий от Twissel

Подозреваю, что html5lib больше рассчитан на валидный хтмл и указывает на ошибки при инвалидном.

Не помню, почему именно оставил BS, но lxml уделывает по скорости всех. Также в lxml есть xpath и cssselect, то есть он довольно удобный, не помню, что там в BS.

anonymous
()
Ответ на: комментарий от anonymous

Не знаю, тянуть целый метаязык, для одного скрипта,

который решает простую и тривиальную задачу.

Тебя Леннарт покусал?!

Twissel ★★★★★
() автор топика
Последнее исправление: Twissel (всего исправлений: 1)
Ответ на: комментарий от anonymous

Наоборот, html5lib рассчитан на любой html, он его фиксит и подготавливает, например, для lxml.

cheerfulboy
()
Ответ на: комментарий от anonymous

Просто, судя по инфе на Гитхабе, библиотека показалась мне громоздкой.

В доки не смотрел.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Indeec

Хотел испробовать для этой задачи именно Питон, в общем понравилось.

А про grab первый раз слышу ;-)

Twissel ★★★★★
() автор топика

Не читай «улучшаторов» из комментов. Скрипт работает и простой - нечего там улучшать. Ну и не совсем понятно, что можно узнать о языке программирования после написанного хеллоуворлда.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

Я тоже так думаю, Оккам говорил: «Не следует умножать сущности без необходимости».

Это как раз такой случай.

Ну и не совсем понятно, что можно узнать о языке программирования после написанного хеллоуворлда.

Ну это просто задача на проверку «холодного старта мозгов».

Хотя даже на этом «пятачке» видно, что Пайтон штука удобная и практичная.

P.S. Но, ради интереса, потыкаю argparse.

Twissel ★★★★★
() автор топика
Последнее исправление: Twissel (всего исправлений: 1)
Ответ на: комментарий от Twissel

Дык grab - либа на питон. Очень удобный парсер хтмл и вроде хмл. вот пример - для чтения баша на работе(лютый быдлокод, но мне норм)

# -*- coding: utf-8 -*-
from grab import Grab
from random import randint
g = Grab()
g.go("http://bash.im/random")
cts = g.doc.select('//div[@class="text"]')
c = randint(1, len(cts)-1)
print "\n%s\n" % cts[c].html().replace("<br>","\n").replace("<div class=\"text\">","").replace("</div>","").replace("&lt;","<").replace("&gt;",">")

Indeec
()
Ответ на: комментарий от Twissel

Там всего-то 600 строк кода.

Если же ты боишься, что лично твой код распухнет, то может быть и правильно боишься, но тебе посоветовали argparse, который ничуть не меньше кода добавит, именно про замену его я и говорил.

Добавлять ли парсинг опций в твой скрипт или нет уже другой вопрос, лично мне все равно.

С docopt это будет выглядеть как-то вот так:

#!/usr/bin/python
"""
Usage: script.py <input> <output>
"""
from docopt import docopt
from bs4 import BeautifulSoup

args = docopt(__doc__)
soup = BeautifulSoup(open(args['<input>'], 'r'))
foutput = open(args['<output>'], 'w')
y = soup.find_all('pre')
for a in y:
    z = a.string
    foutput.write(z)

anonymous
()
Ответ на: комментарий от anonymous

Спасибо, конструктивный ответ :-)

Можно такой же пример с argparse?

Пятница нынче, пока лень смотреть доки Питона.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel
import argparse, sys

parser = argparse.ArgumentParser(description='Example description')
parser.add_argument('input', nargs='?', type=argparse.FileType('r'), default = sys.stdin)
parser.add_argument('output', nargs='?', type=argparse.FileType('w'), default = sys.stdout)
args = parser.parse_args()

print(args.input)
print(args.output)
anonymous
()

sudo cast emulek, а как бы с этой задачей справился sed?

Чистое любопытство :-)

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Это кто-то другой предоставил пример, и я честно говоря думал будет хуже.

anonymous
()
Ответ на: комментарий от anonymous

Тут мне в голову пришло следующее наркоманство: а возможно ли все пары аргументов

fileN.html fileN.c

запихнуть в словарь, а потом спарсить их?

Может тогда использование docopt будет более целесообразно?

Twissel ★★★★★
() автор топика
Последнее исправление: Twissel (всего исправлений: 1)
Ответ на: комментарий от Twissel

Это docstring, строка документации, стандартный способ документирования кода в питоне. В данном случае это документация к модулю, поскольку находится на глобальном уровне видимости в начале модуля. Докстринг любого объекта доступен в атрибуте __doc__. Для модуля:

import module 
print(module.__doc__)

Но твоя программулина оформлена как скрипт, а не как модуль.

Upd. Посмотрел код анонимуса, видимо, там очередной лайфхак на соглашениях используется, docopt берет список аргументов из специальным образом оформленного докстринга, хороший вариант, в принципе.

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от Virtuos86

Да, оригинальное решение.

В остальном, понял.

Получил удовольствие от «допиливания» скрипта на основе ваших подсказок, ребята!

Всем хороших выходных!

Twissel ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.