Python3 Selenium парсинг поиска с Вконтакте через proxy

2017-06-24 | 21:11
Tags: • python djangolife experienceselenium
Задача состояла в том, чтобы спарсить все ID девушек, с возрастом от 18 до 32 лет, из определенных стран и городов.
Было несколько основных проблем:
Доступ с домашнего Ip адреса был закрыт по новому Закону Украины)
Поиск по фильтрам производился благодаря скрипту и без перезагрузки страницы, так что приходилось вручную выбирать страну, город, и возраст от - до.
Решением было использовать Selenium. С этим модулем я раньше не был знаком, но пару раз видел видео, где его используют как раз для симуляции действий пользователя
Команда для консоли Linux (Ubuntu)
sudo pip3 install selenium
Так же нам понадобиться модуль, который позволяет задавать таймаут между командами программы. 
# -*- coding: cp1251 -*-
from selenium import webdriver # импорт селениума
import time # подключаем модуль для тайм аута
PROXY = "85.143.218.246:3128" # прокси для подключения к вконтfrnt с Украины
COUNTRIES = [11,13,14,15,20,21,37,52,53,76,90,92,93,98,118,145,148,150,166,167,174,216,223,225,226] # Города, это номера селекторов, которые выпадают при ручном выборе
AGES = [6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]# номера селекторов по счету, которые определяют возраст от - до
SITIES = range(6,20) # города, так как заранее не понятно какие города будут в конкретной стране, мы просто перебираем по одному в списке

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--proxy-server=%s' % PROXY) # подключение через прокси
Для того чтобы selenium запустил браузер для проведения тестов и программных манипуляций, необходимо установить chromedriver командой
sudo pip3 install chromedriver
далее нужно скачать файл
https://sites.google.com/a/chromium.org/chromedriver/downloads
выбираем последнюю версию, скачиваем
driver = webdriver.Chrome('/home/andrew/Рабочий стол/test/chromedriver', chrome_options=chrome_options)
home/andrew/Рабочий стол/test/chromedriver - указываем здесь путь к файлу который скачали
driver.get("https://vk.com/search")
указываем сайт который должен открываться после запуска программы. Это как раз страница поиска.
Бесплатные прокси я брал из этого сайта. Использовал русские IP, они быстро работают, и пропускаются VK.COM
 
ВЕСЬ КОД ДЛЯ ПАРСИНГА:
# -*- coding: cp1251 -*-
from selenium import webdriver
import time

PROXY = "81.91.188.208:8080" # IP:PORT or HOST:PORT
COUNTRIES = [11,13,14,15,20,21,37,52,53,76,90,92,93,98,118,145,148,150,166,167,174,216,223,225,226]
AGES = [6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
SITIES = range(9,20)


chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--proxy-server=%s' % PROXY)

driver = webdriver.Chrome('/home/andrew/Рабочий стол/test/chromedriver', chrome_options=chrome_options)
driver.get("https://vk.com/search")

time.sleep(1)
driver.find_element_by_xpath('//*[@id="cSex"]/div[1]').click()  # Женский пол

for country in COUNTRIES:
    time.sleep(3)
    driver.find_element_by_xpath('//*[@id="container3"]/table/tbody/tr/td[1]/input[1]').click()  # Активация стран

    time.sleep(1)
    strana = driver.find_element_by_xpath('//*[@id="container3"]/div/div/ul/li[{}]'.format(country)).text
    driver.find_element_by_xpath('//*[@id="container3"]/div/div/ul/li[{}]'.format(country)).click()  # Выбор страны

    for sity in SITIES:
        time.sleep(3)
        driver.find_element_by_xpath('//*[@id="container2"]/table/tbody/tr/td[1]/input[1]').click()  # Активация городов

        time.sleep(2)
        try:
            sit = driver.find_element_by_xpath('//*[@id="container2"]/div/div/ul/li[{}]'.format(sity)).text
            driver.find_element_by_xpath('//*[@id="container2"]/div/div/ul/li[{}]'.format(sity)).click()  # Выбор города
        except:
            break

        for age in AGES:
            time.sleep(2)
            driver.find_element_by_xpath(
                '//*[@id="container13"]/table/tbody/tr/td[1]/input[1]').click()  # Активация возраста "от"

            time.sleep(1)
            ag = driver.find_element_by_xpath(
                '//*[@id="container13"]/div/div/ul/li[{}]'.format(age)).text
            driver.find_element_by_xpath(
                '//*[@id="container13"]/div/div/ul/li[{}]'.format(age)).click()  # Выбор возраста от 18
            time.sleep(3)

            driver.find_element_by_xpath(
                '//*[@id="container14"]/table/tbody/tr/td[1]/input[1]').click()  # Активация возраста "до"

            time.sleep(1)
            driver.find_element_by_xpath(
                '//*[@id="container14"]/div/div/ul/li[2]').click()  # выбор возраста до 18


            try:
                #Определение числа юзеров в фильтре
                time.sleep(3)
                users = int(driver.find_element_by_xpath('//*[@id="search_header"]/div[3]/span').text.replace(' ', ''))


                # Скроллинг кдо конца страницы
                if (users > 1500):
                    users = 1500
                for i in range(int(users/20)):
                    time.sleep(2)
                    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")



                # Парсинг айдишников
                name = driver.find_elements_by_xpath('//div[@class="labeled name"]/a')
                f = open('pars.csv', 'a')
                for i in name:
                    print(i.get_attribute('href'), strana, sit, ag)
                    f.write(strana + ' ' +  sit + '   ' + ag + ' ' + str(i.get_attribute('href')) + '\n')
                f.close()
                print('=' * 30)
            except:
                pass


            # Переопределение
            time.sleep(1)
            driver.find_element_by_xpath('//*[@id="container13"]/table/tbody/tr/td[1]/input[1]').click()
            time.sleep(2)
            driver.find_element_by_xpath('//*[@id="container13"]/div/div/ul/li[1]').click()
            time.sleep(1)
            driver.find_element_by_xpath('//*[@id="container14"]/table/tbody/tr/td[1]/input[1]').click()
            time.sleep(2)
            driver.find_element_by_xpath('//*[@id="container14"]/div/div/ul/li[1]').click()
 
Код разбит на три вложенных цикла
Цикл который перебирает все возрасты
Цикл который перебирает все города
Цикл для стран
В блоке # Переопределение
мы снова возвращаем значение возраста по умолчанию до определения другого города, так как определение новых возрастов иногда неправильно срабатывает с Java скриптом. Долго тестировал и морочился с этим, такой костыль очень помог
В блоке # Парсинг айдишников
мы дозаписываем в созданный документ все айдишники со страницы которые находятся в теге "a" c атрибутом "http"
Так как при выборе всех параметров на странице (Страна, город, возраст) нам показывают только около 20 анкет, но при скроле вниз появляются еще 20, нам необходимо проскролить вниз до тех пор, пока не закончатся анкеты, или не сработает ограничитель - просто подгружаться не будут больше. Как правило выдает от 600 до 1200 анкет при максимальном скроллинге.
В блоке # Скроллинг до конца страницы
мы парсим количество анкет, делим на 20 и столько же раз мы выполняем код скроллинга, но не более чем на 1200 анкет, так как более и не требуется)
В блоке выбора городов мы используем выражение которое позволит прекратить переключение городов, если их больше нет
Очень важно использование тайм аутов, так как при симуляции действий пользователя мы выполняем действия с элементами которые работают на JavaScript и выполняются не мгновенно.
Тек же рекомендую после каждой команды делать паузу от 1 до 3 секунд, в зависимости от сложности последующей подгрузки данных.

 

ubuntu install django
python обучение с нуля
ssd для ноутбука acer
сайт на python