Найти - Пользователи
Полная версия: Как получить данные из таблицы с сайта ( парсинг )
Начало » Web » Как получить данные из таблицы с сайта ( парсинг )
1
pyhappy
Всем привет. Я новичек.

Сейчас пробую получить данные из базы 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 установлены
pill
Ежели это разовая акция то, как по мне, проще набросать велосипедик на 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')
pyhappy
pill
Ежели это разовая акция то, как по мне, проще набросать велосипедик на regexpах и не мучиться.
…..
Спасибо. Только 2 неделю знакомлюсь с питоном. Думал что можно проще описать.
Буду разбираться с кодом. Потом выложу с комментариями для новичков!

И просто для понимания, - если писать на BeautifulSoup - код был бы длиннее и сложнее? :)
pill
Я себя так ни с одной из этих библиотек и не заставил пока разобраться, так что не скажу…
Может кто мимо проходить будет - подскажет.
py.user.next
  находишь запись:
<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 для разбора тегов
используй конечный автомат для классификации данных
Zyamilon
py.user.next
py.user.next
используй htmllib для разбора тегов
Это из стандартной библиотеки? Какая версия питона?
py.user.next
в 2.6 есть
pyhappy
Добавил свои комментарии к коду 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
sypper-pit
pyhappy
хорошее пособие для новичка
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB