Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 5, 2022 23:08:15

Pozi
Зарегистрирован: 2022-10-05
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг картинки разбитой на плитки (как карты)

Добрый день. Нужна помощь!

Нужно выкачать большую картинку с сайта, на сайте она хранится в виде плиток 256*256 пикс
Нашел под эту задачу готовый скрипт, он работает, но есть проблема, точнее 2

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

 Traceback (most recent call last):
  File "C:\gigapandown\gigapanDownloader.py", line 95, in <module>
    h = urlopen(url)
  File "C:\Python27\lib\urllib.py", line 87, in urlopen
    return opener.open(url)
  File "C:\Python27\lib\urllib.py", line 213, in open
    return getattr(self, name)(url)
  File "C:\Python27\lib\urllib.py", line 350, in open_http
    h.endheaders(data)
  File "C:\Python27\lib\httplib.py", line 1038, in endheaders
    self._send_output(message_body)
  File "C:\Python27\lib\httplib.py", line 882, in _send_output
    self.send(msg)
  File "C:\Python27\lib\httplib.py", line 844, in send
    self.connect()
  File "C:\Python27\lib\httplib.py", line 821, in connect
    self.timeout, self.source_address)
  File "C:\Python27\lib\socket.py", line 557, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
IOError: [Errno socket error] [Errno 11001] getaddrinfo failed

2 хорошо бы еще распараллелить загрузку, а то плитки грузятся в 1 поток крайне медленно (
но это уже фантазии, и решить хотя бы 1ую проблему, уже было бы замечательно

вот сам цикл загрузки плиток
или лучше весь скрипт выложить?
 #loop around to get every tile
for j in xrange(ht):
    for i in xrange(wt):
        filename = "%04d-%04d.jpg"%(j,i)
        pathfilename = str(photo_id)+"/"+filename
        if not os.path.exists(pathfilename) :
            url = "%s/get_ge_tile/%d/%d/%d/%d"%(base,photo_id, level,j,i)
            progress = (j)*wt+i+1
            print '('+str(progress)+'/'+str(wt*ht)+') Downloading '+str(url)+' as '+str(filename)
            h = urlopen(url)
            if 200 == h.code :
                fout = open(pathfilename,"wb")
                fout.write(h.read())
                fout.close()
            else:
                print '('+str(progress)+'/'+str(wt*ht)+') Downloading error '+str(url)+' http code '+str(h.code)
                ++errors

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

Офлайн

#2 Окт. 5, 2022 23:59:43

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9873
Репутация: +  853  -
Профиль   Отправить e-mail  

парсинг картинки разбитой на плитки (как карты)

Во-первых, это к Data Mining никакого отношения не имеет. Data Mining - это добывание данных из данных. Это когда у тебя есть какие-то данные и из них на основе гипотез с помощью математической статистики добывают какие-то новые данные.

Во-вторых, написание программы начинается не с написания чего-то там и дальнейшего понимания по этому написанному, а что же, собственно, пишется. Сначала нужно задачу описать без всякого кода словами от начала и до конца, не оставляя никаких неясностей. В начале у тебя что-то конкретное дано. В конце у тебя что-то конкретное получено. И только после того, как это словесное описание готово, можно приступать к его дальнейшей реализации, которая тоже не сразу в виде кода происходит. Сначала рисуется блок-схема (сейчас можно использовать UML-диаграммы для этого), потом блок-схема оптимизируется, потом в результате этой оптимизации оптимизируется словесное описание, полученное на предыдущем этапе разработки, и снова строится блок-схема по этому оптимизированному словесному описанию. Когда словесное описание оптимально и когда блок-схема оптимальна, пишется псевдокод по этой блок-схеме. Потом псевдокод оптимизируется, а за ним, возможно, оптимизируется блок-схема, а за ней, возможно, оптимизируется словесное описание и потом всё повторяется. Это такой итеративный процесс, когда ты всё время оптимизируешь и возвращаешься в начало. Так у тебя постепенно всё улучшается и всё уточняется до самых мелких деталей. И вот когда вся эта цепочка получена и в ней всё оптимально, тогда ты и пишешь уже конечный код по этому псевдокоду. А там уже остаётся только записать код. После того, как код будет записан, с ним надо будет дальше работать - обслуживать его. Соответственно, там и комментарии должны быть, и юнит-тесты должны быть, и репозиторий должен быть, и установщик программы должен быть, и документация должна быть как по установке программы, так и по самой программе. И эта документация должна быть понятна абсолютно незнакомому с этой программой человеку.

Вот что такое программирование.

А вот это твоё “в свое время в универе все писал на делфи” не значит ничего, потому что всего этого - всего того, что нужно знать, - ты не знаешь.

В-третьих, опиши всё для нас на словах и выложи свои кодовые наработки, чтобы мы могли из твоего описания и твоего кода просто понять, что тебе нужно сделать, какую задачу ты решаешь, потому что вот это “Нужно выкачать большую картинку с сайта, на сайте она хранится в виде плиток 256*256 пикс” - это не описание, а это ни пойми что. 100500 способов есть выкачивания и 100500 способов есть хранения и какие из них подходят под твой случай из этого описания никак не определишь.



Офлайн

#3 Окт. 6, 2022 09:18:41

Pozi
Зарегистрирован: 2022-10-05
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг картинки разбитой на плитки (как карты)

py.user.next
есть выкачивания и 100500 способов есть хранения и какие из них подходят под твой случай из этого описания никак не определишь.


проблема не в хранении…. про хранение я даже слова не написал
проблема именно в загрузке

объяснить на словах? так я же вроде уже
есть картинка из плиток, допустим 1000*500 плиток = 500 000 плиток, по сути это как парсинг карт гугл или яндекса,
тоже самое, карта состоит из плиток, их нужно выкачать все

скрипт все закачивает, все работает, оно качает, хранит, это все нормально, в целом то скрипт рабочий
НООООО
1 отваливается периодически сервер и все встает, и нужно запускать руками званого.
человек написавший скрипт видимо не предусмотрел такую проблему (
при чем всегда по разному, то часами загружает плитки, то бывает каждые 15 минут ошибку выдает
2 медленно закачивается в 1 поток

 from xml.dom.minidom import *
from urllib2 import *
from urllib import *
import sys,os,math,subprocess
outputformat="psb" #psb or tif
imagemagick="/usr/bin/montage" #Linux path to Imagemagick
if os.name == "nt":
  imagemagick="C:\\Program Files\\ImageMagick-6.9.9-Q16\\montage.exe" #Windows path to Imagemagick
def getText(nodelist):
    rc = ""
    for node in nodelist:
        if node.nodeType == node.TEXT_NODE:
            rc = rc + node.data
    return rc
def find_element_value(e,name):
    nodelist = [e]
    while len(nodelist) > 0 :
        node = nodelist.pop()
        if node.nodeType == node.ELEMENT_NODE and node.localName == name:
            return getText(node.childNodes)
        else:
            nodelist += node.childNodes
    return None
#main
photo_id = int(sys.argv[1])
if not os.path.exists(str(photo_id)):
    os.makedirs(str(photo_id))
base = "http://www.gigapan.org"
# read the kml file
h = urlopen(base+"/gigapans/%d.kml"%(photo_id))
photo_kml=h.read()
# find the width and height, level 
dom = parseString(photo_kml)
maxheight=int(find_element_value(dom.documentElement, "maxHeight"))
maxwidth=int(find_element_value(dom.documentElement, "maxWidth"))
tile_size=int(find_element_value(dom.documentElement, "tileSize"))
maxlevel = max(math.ceil(maxwidth/tile_size), math.ceil(maxheight/tile_size))
maxlevel = int(math.ceil(math.log(maxlevel)/math.log(2.0)))
maxwt = int(math.ceil(maxwidth/tile_size))+1
maxht = int(math.ceil(maxheight/tile_size))+1
# find the width, height, tile number and level to use
level = int(sys.argv[2])
if level == 0: 
  level = maxlevel
width = int(maxwidth / (2 ** (maxlevel-level)))+1
height = int(maxheight / (2 ** (maxlevel-level)))+1
wt = int(math.ceil(width/tile_size))+1
ht = int(math.ceil(height/tile_size))+1
# print the variables
print '+----------------------------'
print '| Max size: '+str(maxwidth)+'x'+str(maxheight)+'px'
print '| Max number of tiles: '+str(maxwt)+'x'+str(maxht)+' tiles = '+str(wt*ht)+' tiles'
print '| Max level: '+str(maxlevel)
print '| Tile size: '+str(tile_size)
print '+----------------------------'
print '| Image to download:'
print '| Size: '+str(width)+'x'+str(height)+'px'
print '| Number of tiles: '+str(wt)+'x'+str(ht)+' tiles = '+str(wt*ht)+' tiles'
print '| Level: '+str(level)
print '+----------------------------'
print
print 'Starting download...'
errors = 0
#loop around to get every tile
for j in xrange(ht):
    for i in xrange(wt):
        filename = "%04d-%04d.jpg"%(j,i)
        pathfilename = str(photo_id)+"/"+filename
        if not os.path.exists(pathfilename) :
            url = "%s/get_ge_tile/%d/%d/%d/%d"%(base,photo_id, level,j,i)
            progress = (j)*wt+i+1
            print '('+str(progress)+'/'+str(wt*ht)+') Downloading '+str(url)+' as '+str(filename)
            h = urlopen(url)
            if 200 == h.code :
                fout = open(pathfilename,"wb")
                fout.write(h.read())
                fout.close()
            else:
                print '('+str(progress)+'/'+str(wt*ht)+') Downloading error '+str(url)+' http code '+str(h.code)
                ++errors

Офлайн

#4 Окт. 7, 2022 00:54:28

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9873
Репутация: +  853  -
Профиль   Отправить e-mail  

парсинг картинки разбитой на плитки (как карты)

Pozi
проблема не в хранении…. про хранение я даже слова не написал
На сайте оно хранится. Соответственно, для закачивания с сайта, нужно сначала понять, где оно хранится, как оно хранится и как это скачать, потому что скачать тоже можно не всегда (может запросить какие-то пользовательские данные).

Pozi
  
++errors
Вот это просто смешно. Ошибки тут синтаксической нет только потому, что это две унарных операции плюс
  
>>> errors = 1
>>> ++errors
1
>>> +(+(errors))
1
>>>
В питоне нет операций прединкремента и постинкремента.

Pozi
объяснить на словах? так я же вроде уже
есть картинка из плиток, допустим 1000*500 плиток = 500 000 плиток, по сути это как парсинг карт гугл или яндекса,
тоже самое, карта состоит из плиток, их нужно выкачать все
Это ты задачу описал. А выполнение этой задачи ты не описал словами.

Это вот смотри. Есть задача купить картошку, например.

И вот словесное описание задачи:
Надо купить картошку в магазине.

И вот словесное описание выполнения (реализации) этой задачи (описание алгоритма, который начинается с того, что дано, и заканчивается тем, что надо получить в результате):

Дано: есть деньги
Получить: дома мешок картошки

1. Взять деньги на картошку.
2. Взять деньги на проезд туда и обратно.
3. Приехать в магазин.
3.1. Позвонить в таксишную фирму.
3.2. Дождаться звонка из фирмы.
3.3. Встретить машину такси.
3.4. Приехать в магазин на такси.
3.5. Расплатиться с водителем такси.
4. Найти картошку в магазине.
5. Купить картошку в магазине.
5.1. Принести картошку на кассу.
5.2. Оплатить картошку и забрать чек.
6. Приехать с картошкой домой.
6.1. Позвонить в таксишную фирму.
6.2. Дождаться звонка из фирмы.
6.3. Встретить машину такси.
6.4. Приехать домой на такси.
6.5. Расплатиться с водителем такси.
7. Занести картошку домой.

Как видишь, каждый из этих пунктов и подпунктов можно уточнять дальше до самых мельчайших деталей. И также видно, что третий пункт и шестой пункт похожи между собой, поэтому тут напрашивается одна общая процедура для них. То есть на этом этапе (на этапе словесного описания) уже видно, что там будет функция поездки на такси, которая будет два раза вызываться - чтобы приехать туда и чтобы приехать обратно. То есть это происходит без всякого кода. Кода ещё нет, а уже всё видно, что там будет в коде.

Это вот то, что ты не умеешь делать, потому у тебя и нет этого описания твоей программы. Вот это - программирование, а Delphi - это не программирование. Результат твоего Delphi - это вот эта мешанина, которую ты написал на данный момент. Всего десять строчек и уже не работает нифига.

Pozi
объяснить на словах? так я же вроде уже
есть картинка из плиток, допустим 1000*500 плиток = 500 000 плиток, по сути это как парсинг карт гугл или яндекса,
тоже самое, карта состоит из плиток, их нужно выкачать все
Вот теперь подробно расписывай по шагам, как ты это делаешь. Куда подключаешься, как оно там хранится, как ты его оттуда скачиваешь (каким способом, нужны ли для скачивания креденшенелы (там печенье или что) или оно всем даёт скачивать анонимно), куда оно сохраняется после скачивания, какой результат на экран выводится во время скачивания и после скачивания и что там должно писаться в этом результате. Вот это всё на словах описывай от начала до конца. Когда оно будет готово, тогда и будешь пробовать код писать по этому словесному описанию. Хотя нужно сначала построить блок-схему, а потом псевдокод написать. Вот это разработка.



Отредактировано py.user.next (Окт. 7, 2022 00:57:33)

Офлайн

#5 Окт. 8, 2022 12:22:26

Pozi
Зарегистрирован: 2022-10-05
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

парсинг картинки разбитой на плитки (как карты)

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

 if errors == 0:
    print "Stitching... "
    for j in xrange(ht):
        lineNo = "%04d"%(j)
        print 'creating line '+ str(lineNo)
        subprocess.call('"'+imagemagick+'" -depth 8 '+
                                        '-geometry 256x256+0+0 ' +
                                        '-mode concatenate ' +
                                        '-tile '+ str(wt)+'x ' +
                                        str(photo_id)+'/'+str(lineNo)+'-*.jpg ' +
                                        str(photo_id)+'/line-'+ str(lineNo) +'.jpg',
                        shell=True)
    wline = wt * 256
    print 'creating output file '
    subprocess.call('"'+imagemagick+'" -depth 8 '+
                    '-geometry '+str(wline)+'x256+0+0 ' +
                    '-mode concatenate ' +
                    '-tile x'+ str(ht)+' ' +
                    str(photo_id)+'/line-*.jpg ' +
                    str(photo_id)+'.'+outputformat,
                    shell=True)
    print "OK"

во первый непонятно почему автор скрипта выбрал jpg
ведь он имеет ограничение в 50000 пикселей, изменил на tif,
с этим теперь все нормально.
но… по умолчанию imagemagick создает кэш в папке пользователя, то есть на диске С
а там места не так уж и много
 subprocess.call('"'+imagemagick+'" -define registry:temporary-path=E:\tmp -depth 8 '+
указал ему место кэша E:\tmp, проблема частично решилась, теперь не сжирает место на диске С
файлы склеиваются, хотя все равно выдает ошибку и я не совсем понимаю что ему не нравится?

montage.exe: unable to open image `mp': No such file or directory @ error/blob.c/OpenBlob/2761.
montage.exe: no decode delegate for this image format `' @ error/constitute.c/ReadImage/504.


py.user.next
Результат твоего Delphi - это вот эта мешанина, которую ты написал на данный момент. Всего десять строчек и уже не работает нифига.

без обид, а ты читать умеешь? или только вот эту чушь писать?
повторяю еще раз
КОД НЕ МОЙ, Я НАШЕЛ ГОТОВЫЙ СКРИПТ И ПЫТАЮСЬ ЕГО ИСПРАВИТЬ
и скрипт работает, просто имеет недостатки
прежде чем писать эти простыни хоть прочитай 5 строчек написанные в 1ом сообщении

Отредактировано Pozi (Окт. 8, 2022 12:22:58)

Офлайн

#6 Окт. 8, 2022 22:20:10

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9873
Репутация: +  853  -
Профиль   Отправить e-mail  

парсинг картинки разбитой на плитки (как карты)

Pozi
повторяю еще раз
КОД НЕ МОЙ, Я НАШЕЛ ГОТОВЫЙ СКРИПТ И ПЫТАЮСЬ ЕГО ИСПРАВИТЬ
и скрипт работает, просто имеет недостатки
повторяю ещё раз
ГОВНО НЕ МОЁ, Я НАШЁЛ ГОТОВОЕ ГОВНО И ПЫТАЮСЬ ИЗ НЕГО СДЕЛАТЬ ТОРТ ОБРАТНО
и говно можно есть чайной ложечкой, оно просто невкусное и какое-то пресное пока что

Вот как будет у тебя то, что я сказал тебе сделать, тогда и приходи за помощью. Мы тут из говна торты не делаем. Мы торты делаем. А чтобы их делать, мы используем соответствующие ингредиенты.



Отредактировано py.user.next (Окт. 8, 2022 22:23:46)

Офлайн

#7 Окт. 9, 2022 12:09:17

xam1816
Зарегистрирован: 2020-05-11
Сообщения: 1352
Репутация: +  118  -
Профиль   Отправить e-mail  

парсинг картинки разбитой на плитки (как карты)

Pozi
Я НАШЕЛ ГОТОВЫЙ СКРИПТ И ПЫТАЮСЬ ЕГО ИСПРАВИТЬ

вот оригинальный код ссылка
(почему сразу не отправили непонятно) под 2й питон
Install Python 2.X (3.X is not supported)
Pozi
во первый непонятно почему автор скрипта выбрал jpg
так там же написано
Select outputformat in gigapanDownloader.py - psb for large gigapans (default) or tif.
Pozi
и скрипт работает, просто имеет недостатки
Расскажите что исправили?


Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version