AlekseyUbuntu, там только с фреймами аккуратнее. Иногда начинаешь разбирать дерево DOM, смотришь на страницу в браузере, видишь там, скажем таблицу. Тыркаешься в this.document.getElementsByTagName('table'), а коллекция пуста. Для меня в свое время откровением стало, что иногда внутри одной страницы живут несколько, запакованные каждая в свой фрейм. Следует проверять их наличие, и обрабатывать соответствующим образом.
Кроме того, бывают случаи, когда данные спарсировать вообще как таковые нельзя в прямом смысле этого слова: веб-страница верстается скриптом прямо на стороне клиента. Однако данные существуют в виде некоего массива, который загружается браузером при старте страницы. Пример такого парсинга (Python) под спойлером, - мало ли будет полезно.
#!/usr/bin/env python
#coding=utf-8
# подключаемые библиотеки:
from urllib2 import urlopen #работа с сетью
from bs4 import BeautifulSoup #работа с DOM
import re #работа с регулярными выражениями
import argparse #получение аргументов из командной строки
import codecs #работа с файлами
import os #работа с операционной системой и выполнение команд bash
import sys #для адекватной работы с кодировками в данном случае
#Сама функция парсирования:
def pars_by_url(url):
response = urlopen(url) #выполняем запрос на сервер
html = response.read() #читаем полученный ответ
soup = BeautifulSoup(html,"lxml") #формируем коллекцию DOM-элементов
outfile=[]
outfile.append('<!DOCTYPE html><html><meta charset="utf-8"><head></head><body><table border="1">')
outfile.append('<tr><td>Имя</td><td>Возраст</td><td>Фото</td><td>Откуда</td></tr>')
for theScript in soup.find_all('script'):
if ( 'web-search-infinite_search_results__0' in unicode(theScript) ):
try:
#нас интересует сперва группа вхождений: "items":[ ... },\n
result4 = re.search(r'"items"\:\[.+\}\,\n',str(theScript))
#теперь отбросим префикс "items":[ - он встречается 1 раз в начале, и все равно не закрыт:
result3 = str(result4.group(0)).replace('"items":[','')
#теперь разобьем результаты по ключевому слову, с которого начинается каждый профиль:
result2 = result3.split('{"profile"')
print 'Всего найдено:'+str(len(result2)-1) #-1, потому что первый элемент будет пустой,
#т.к. строка начаинается с разделителя '{"profile"'
for result in result2:
if ( result != '' ): #обходим пустой результат
curstrOF=''
keyPairs=re.findall(r'"[^"]+":"[^"]+"|"[^"]+":[0-9]+|"[^"]+":"http[^"]"',str(result)) #получаем набор данных вида "Ключ":"Значение"
#print 'Имя: '+str(keyPairs[2].split(':')[1]).replace('"',"")
curstrOF=curstrOF+'<td>'+str(keyPairs[2].split(':')[1]).replace('"',"")+'</td>'
#пример организации поиска именованных параметров
for param in keyPairs:
param_key = str(param.split(':')[0]).replace('"',"")
if param_key == 'selfAge':
curstrOF=curstrOF+'<td>'+str(param.split(':')[1]).replace('"',"")+'</td>'
#print 'Возраст: '+ str(param.split(':')[1]).replace('"',"")
if param_key == 'location':
#print 'Откуда: '+ str(param.split(':')[1]).replace('"',"")
curstrOF=curstrOF+'<td>'+str(param.split(':')[1]).replace('"',"")+'</td>'
if param_key == 'photo':
curstrOF=curstrOF+'<td><img src='+str(param.split('":"')[1]).replace('"',"").replace('\/','/')+'+></td>'
#print 'Фото: '+ str(param.split('":"')[1]).replace('"',"").replace('\/','/')
outfile.append('<tr>'+curstrOF+'</tr>')
outfile.append('</table></body></html>')
#print outfile
print "Информация спарсирована. Выполняется сохранение файла..."
#сохранение результата в файл:
fname=os.getenv('HOME')+'/анкеты.html' #вычисляем имя файла
print fname
fp = codecs.open(fname, 'w', encoding='utf-8') #открываем файл для записи
for curString in outfile: #построчное заполнение файла
print str(curString)
fp.write( unicode(curString) )
fp.close() #закрытие файла
print 'Результат сохранен в файл: ['+fname+']'
bashCommand = 'firefox "'+fname+'" & '
os.system(bashCommand) #открытие файла в firefox
except:
print "сбой поиска"
#Сама программа (разбираем аргументы, и вызываем парсер):
def main():
reload(sys)
sys.setdefaultencoding('utf8')
callWith=argparse.ArgumentParser()
callWith.add_argument('--city', help='Город Ростовской области')
args = callWith.parse_args()
if ( args.city != None ):
# заполняем словарь
city_list = {}
city_list ["Азов"] = 4801
city_list ["Аксай"] = 4802
city_list ["Александровка"] = 1000279212
city_list ["Багаевская"] = 1000279259
city_list ["Батайск"] = 4806
city_list ["Белая Калитва"] = 4807
city_list ["Боковская"] = 4808
city_list ["Большая Мартыновка"] = 4809
city_list ["Большая Орловка"] = 1000279263
city_list ["Большие Салы"] = 1000279265
city_list ["Большой Лог"] = 1000279253
city_list ["Быстрогорский"] = 1000279325
city_list ["Весёлый"] = 1000279240
city_list ["Вешенская"] = 4810
city_list ["Волгодонск"] = 4811
city_list ["Гигант"] = 4813
city_list ["Глубокий"] = 1000279338
city_list ["Горный"] = 1000279307
city_list ["Горняцкий"] = 4814
city_list ["Грушевская"] = 1000279275
city_list ["Гуково"] = 4815
city_list ["Донецк"] = 4816
city_list ["Дубовское"] = 4818
city_list ["Егорлыкская"] = 7592215
city_list ["Елкин"] = 1000279261
city_list ["Жирнов"] = 4819
city_list ["Заветное"] = 4820
city_list ["Зверево"] = 4822
city_list ["Зерноград"] = 4823
city_list ["Зимовники"] = 4824
city_list ["Кагальник"] = 1000279235
city_list ["Кагальницкая"] = 4825
city_list ["Казанская"] = 4826
city_list ["Калинин"] = 1000279244
city_list ["Каменоломни"] = 4827
city_list ["Каменск-Шахтинский"] = 4828
city_list ["Кашары"] = 4829
city_list ["Кировская"] = 1000279227
city_list ["Коксовый"] = 4830
city_list ["Константиновск"] = 4831
city_list ["Красная Поляна"] = 1000279195
city_list ["Красноармейский"] = 1000279229
city_list ["Красновка"] = 1000279342
city_list ["Красноярская"] = 1000279279
city_list ["Красный Сулин"] = 4832
city_list ["Красюковская"] = 1000279288
city_list ["Кривянская"] = 1000279267
city_list ["Крым"] = 1000279257
city_list ["Куйбышево"] = 4833
city_list ["Кулешовка"] = 1000279233
city_list ["Летник"] = 1000279194
city_list ["Лихой"] = 1000279312
city_list ["Мальчевская"] = 1000279348
city_list ["Маньково-Калитвенское"] = 1000279352
city_list ["Матвеев Курган"] = 4834
city_list ["Мечетинская"] = 1000279211
city_list ["Миллерово"] = 4836
city_list ["Милютинская"] = 4837
city_list ["Морозовск"] = 4838
city_list ["Николаевская"] = 1000279292
city_list ["Новобатайск"] = 1000279222
city_list ["Новобессергеневка"] = 1000279242
city_list ["Новочеркасск"] = 4839
city_list ["Новошахтинск"] = 4840
city_list ["Новый Егорлык"] = 1000279203
city_list ["Обливская"] = 4841
city_list ["Ольгинская"] = 1000279241
city_list ["Орловский"] = 4842
city_list ["Персиановский"] = 1000279285
city_list ["Песчанокопское"] = 4843
city_list ["Пешково"] = 1000279231
city_list ["Покровское"] = 4844
city_list ["Приморка"] = 1000279248
city_list ["Пролетарск"] = 4845
city_list ["Развильное"] = 1000279199
city_list ["Рассвет"] = 1000279213
city_list ["Ремонтное"] = 4846
city_list ["Родионово-Несветайская"] = 4847
city_list ["Романовская"] = 1000279287
city_list ["Ростов-на-Дону"] = 4848
city_list ["Сальск"] = 4849
city_list ["Самарское"] = 1000279225
city_list ["Сандата"] = 1000279201
city_list ["Семикаракорск"] = 4850
city_list ["Синегорский"] = 1000279309
city_list ["Синявское"] = 1000279249
city_list ["Советская"] = 1000279344
city_list ["Старая Станица"] = 1000279335
city_list ["Таганрог"] = 4851
city_list ["Тарасовский"] = 4852
city_list ["Тацинская"] = 1000279323
city_list ["Углегорский"] = 1000279319
city_list ["Углеродовский"] = 1000279313
city_list ["Усть-Донецкий"] = 4854
city_list ["Целина"] = 4855
city_list ["Цимлянск"] = 4856
city_list ["Чалтырь"] = 4857
city_list ["Чертково"] = 4858
city_list ["Шахты"] = 4859
city_list ["Шолоховский"] = 4860
for city in city_list:
#print city
if ( args.city.lower() == city.lower() ):
city_id = city_list[city]
else:
#"любой город"
city_id = 0
myURL = 'https://love.mail.ru/ru/search.phtml?ia=M&lf=F&af=22&at=29&p=a&t=z&s_c=3159_4800_'+str(city_id)+'_0&form=1'
pars_by_url(myURL)
#вызов главной процедуры
if __name__ == '__main__':
main()
Как работает. Сохраняем этот текст в файл Парсинг_майл_ру.py. Открываем терминал, выполняем cd в каталог, в котором скрипт, и далее запускаем:
python Парсинг_майл_ру.py
python Парсинг_майл_ру.py --city Азов
И да: руками оно кошернее )) Selenium - хороший выбор. По сути, то же, что я применяю на работе, но с прицелом под Linux.