Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Web
  • » Как получить данные из таблицы с сайта ( парсинг ) [RSS Feed]

#1 Ноя. 13, 2011 12:59:44

pyhappy
От: Moscow/Russia
Зарегистрирован: 2011-11-13
Сообщения: 22
Репутация: +  0  -
Профиль  

Как получить данные из таблицы с сайта ( парсинг )

Всем привет. Я новичек.

Сейчас пробую получить данные из базы http://www.mebelrus.ru/base/tema-1/region-111/city-377/ на которой 19 страниц с 20 ссылками на каждой

Нужно выгрузить в таком формате 4 поля в txt файл с разделителями, на примере 2 первых записей

—-
1) Название: “1-я фабрика нестандартной мебели” // далее нужно пройти по ссылке и получить детали из новой отрытой таблицы
2) Адрес: 129323, г. Москва, Лазоревый проезд, д. 1
3) Тел: (495) 740-82-42, факс: (499) 189-92-03
4) Описание: Производство кухонь на заказ из массива дуба, ясеня, МДФ по индивидуальным проектам.
—–
1) Название: “2 Брата”, мебельная фабрика // далее нужно пройти по ссылке и получить детали из новой отрытой таблицы
2) Адрес: 100000, г. Москва, Тушинская ул., д. 16, оф. 3
3) Тел: (495) 514-84-14
4) Описание: Производство мебели на заказ по индивидуальным проектам.

Пол дня искал подобные примеры в гугле но так и не нашел, буду признателен за помощь.

p.s.
Питон 2.6, также BeautifulSoup, mechaniz, libxml установлены

Офлайн

#2 Ноя. 13, 2011 16:20:49

pill
От:
Зарегистрирован: 2010-08-27
Сообщения: 223
Репутация: +  0  -
Профиль   Отправить e-mail  

Как получить данные из таблицы с сайта ( парсинг )

Ежели это разовая акция то, как по мне, проще набросать велосипедик на regexpах и не мучиться.

что то вроде:

import urllib2
import re
import sys

base_urls = ['http://www.mebelrus.ru/base/tema-1/region-111/city-377',]
for i in xrange(1,19):
base_urls.append('-'.join((base_urls[0], str(i))))

urls = []
for num, url in enumerate(base_urls):
s = urllib2.urlopen(url + '/')
data = s.read()
s.close()
urls.extend(re.findall('<div class="cityfirm"><a href="(.+?)".+?</div>',
data, re.DOTALL))

sys.stdout.write("\rFetching urls %d/%d" % (num + 1, len(base_urls)))
sys.stdout.flush()

res = []

for num, url in enumerate(urls):
s = urllib2.urlopen(url + '/')
data = s.read()
s.close()

name = re.findall('<h1 class="firma">(.+?)</h1>', data, re.DOTALL)[0]
info = re.findall('<div class="opis">(.+?)</div>', data, re.DOTALL)[0]
info = re.sub('<br />|<div class="des">', '\n', info, re.DOTALL)
info = re.sub('&nbsp;|<.+?>', '', info, re.DOTALL)
info = re.sub('\n\n', '\n', info, re.DOTALL)
res.append('\n'.join((u'Название: ' + name, info)))

sys.stdout.write("\rFetching data %d/%d" % (num + 1, len(urls)))
sys.stdout.flush()

with open('data.txt', 'w') as f:
f.write('\n------------\n'.join(res))

print('\nsaved')



Офлайн

#3 Ноя. 13, 2011 17:33:09

pyhappy
От: Moscow/Russia
Зарегистрирован: 2011-11-13
Сообщения: 22
Репутация: +  0  -
Профиль  

Как получить данные из таблицы с сайта ( парсинг )

pill
Ежели это разовая акция то, как по мне, проще набросать велосипедик на regexpах и не мучиться.
…..
Спасибо. Только 2 неделю знакомлюсь с питоном. Думал что можно проще описать.
Буду разбираться с кодом. Потом выложу с комментариями для новичков!

И просто для понимания, - если писать на BeautifulSoup - код был бы длиннее и сложнее? :)

Отредактировано (Ноя. 13, 2011 17:37:09)

Офлайн

#4 Ноя. 13, 2011 18:40:47

pill
От:
Зарегистрирован: 2010-08-27
Сообщения: 223
Репутация: +  0  -
Профиль   Отправить e-mail  

Как получить данные из таблицы с сайта ( парсинг )

Я себя так ни с одной из этих библиотек и не заставил пока разобраться, так что не скажу…
Может кто мимо проходить будет - подскажет.



Офлайн

#5 Ноя. 14, 2011 00:09:14

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

Как получить данные из таблицы с сайта ( парсинг )

  находишь запись:
<div class="cityfirm">
<a href="http://www.mebelrus.ru/base/tema-1/region-111/city-377/firm-15220/" class="cityfirm">
"1-я фабрика нестандартной мебели"
</a>
</div>
<div class="opis2">
129323, г. Москва, Лазоревый проезд, д. 1 <br />
<span class="des">
Описание:&nbsp;Производство кухонь на заказ из массива дуба, ясеня, ...
</span>
</div>

переходишь к данным записи:
<h1 class="firma">
"1-я фабрика нестандартной мебели"
</h1>
<div class="opis">
129323, г. Москва, Лазоревый проезд, д. 1 <br />
тел: (495) 740-82-42<br />
факс: (499) 189-92-03
<div class="des">
<span class="desfon">
&nbsp;Описание:&nbsp;
</span>
&nbsp;Производство кухонь на заказ из массива дуба, ясеня, МДФ по индивидуальным проектам.
</div>
<div class="des">
<span class="desfon">
&nbsp;Производственные площади:&nbsp;
</span>
&nbsp;700 кв. м.
</div>
<div class="des">
<span class="te">
информация внесена:
</span>
27.07.2011 г.
</div>
</div>
используй urllib для получения страниц
используй htmllib для разбора тегов
используй конечный автомат для классификации данных



Офлайн

#6 Ноя. 14, 2011 11:03:36

Zyamilon
От:
Зарегистрирован: 2011-11-13
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Как получить данные из таблицы с сайта ( парсинг )

py.user.next

py.user.next
используй htmllib для разбора тегов
Это из стандартной библиотеки? Какая версия питона?



Офлайн

#7 Ноя. 14, 2011 22:30:28

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

Как получить данные из таблицы с сайта ( парсинг )

в 2.6 есть



Офлайн

#8 Ноя. 16, 2011 20:04:18

pyhappy
От: Moscow/Russia
Зарегистрирован: 2011-11-13
Сообщения: 22
Репутация: +  0  -
Профиль  

Как получить данные из таблицы с сайта ( парсинг )

Добавил свои комментарии к коду Pill (для себя и других зеленых новичков)

import urllib2 #Модуль для работы с протоколом HTTP, высокоуровневый
import re #модуль для работы с регулярными варажениями
import sys # системный модуль

base_urls = ['http://www.mebelrus.ru/base/tema-1/region-111/city-377',]
#начальная урл - http://www.mebelrus.ru/base/tema-1/region-111/city-377/
# каждая следующая страница отличается в конце
# http://www.mebelrus.ru/base/tema-1/region-111/city-377-1/ -19 итд
for i in xrange(1,19):
base_urls.append('-'.join((base_urls[0], str(i))))
#Append - добавляет в список новое значение последним
# значение формируется специальным образом
#[0] - значит что в качестве базового используется первоначальный URl
# для этого используется оператор Join с номером страницы, которая
# обрабатывается счетчиком через xrange(1, 19) (19 не включая)
print(base_urls)

urls = [] #здесь будут ссылки на детальное описание каждой фирмы
for num, url in enumerate(base_urls): #проход по всем 18 полученным ссылкам
s = urllib2.urlopen(url + '/') #добавляем в конце косую черту и открываем
data = s.read() #считываем содержимое кажжой страницы в переменную data
s.close() #закрывает
urls.extend(re.findall('<div class="cityfirm"><a href="(.+?)".+?</div>',
data, re.DOTALL))
#добавляем в список найденные данные по запросу с регулярным варажениям
# те получаем ссылки на детальное описание каждой фирмы на каждой из 18 стр
#print (urls)
sys.stdout.write("\rFetching urls %d/%d" % (num + 1, len(base_urls)))
# len(base_urls)- число элементов списка - количество страниц (те 18)
sys.stdout.flush()
# так и не смог найти зачем эта строка нужна, вроде что-то выталкивает

res = [] #пустой список будущих выводов

for num, url in enumerate(urls): #проход по всем ссылками, полученным на 18 стр
s = urllib2.urlopen(url + '/') #добавляем в конце косую черту и открываем
data = s.read() #считываем содержимое кажжой страницы в переменную data
s.close() #закрывает

#готовим финальные данные с помощью рег.выр.
name = re.findall('<h1 class="firma">(.+?)</h1>', data, re.DOTALL )[0]
info = re.findall('<div class="opis">(.+?)</div>', data, re.DOTALL )[0]

# получили name и info но их нужно исправить, тк содержится мусор
info = re.sub('<br />|<div class="des">', '\n', info, re.DOTALL ) #заменяем на пернос
info = re.sub('&nbsp;|<.+?>', '', info, re.DOTALL ) #заменяем грязь на пусто
info = re.sub('\n\n', '\n', info, re.DOTALL ) #заменяем двойной пробел на одинарный

res.append('\n'.join(('Название: ' + name, info))) # добавляем в конец
# перенос на след строку + на новой строке переменную имя

sys.stdout.write("\rFetching data %d/%d" % (num + 1, len(urls)))
#выводим информационное сообщение где len(urls)- общее число фирм
sys.stdout.flush()

with open('data.txt', 'w') as f:
f.write('\n--------------\n'. join(res))
# объединяем все элементы списка с разделителем ------ + новая строка

print('\nsaved') # alldone

Офлайн

#9 Ноя. 18, 2011 00:10:25

sypper-pit
От: Ulan-Ude(msk)
Зарегистрирован: 2009-01-30
Сообщения: 1102
Репутация: +  6  -
Профиль   Отправить e-mail  

Как получить данные из таблицы с сайта ( парсинг )

pyhappy
хорошее пособие для новичка

Офлайн

  • Начало
  • » Web
  • » Как получить данные из таблицы с сайта ( парсинг )[RSS Feed]

Board footer

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

Powered by DjangoBB

Lo-Fi Version