Как нажать несколько кнопок «+» на странице в хронологическом порядке и извлечь данные из них с помощью Python? - PullRequest
0 голосов
/ 07 марта 2019

Мне нужно извлечь номер телефона и ссылки на веб-сайт вместе с названием и страной университетов с веб-сайта.Веб-сайт https://www.whed.net/results_institutions.php?Chp2=Business%20Administration, и проблема в том, что существует знак +, который нужно щелкнуть для каждого университета, затем необходимо извлечь данные, закрыть и перейти к следующему.

Я пробовал несколько способов применения селена следующим образом:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.keys import Keys
import time
from bs4 import BeautifulSoup
import pandas as pd

#opening the web browser
browser = webdriver.Chrome('C:\\Users\\albert.malhotra\\Desktop\\Web Scrapings\\Kentucky State\\chromedriver')

#assigning the link to a variable
url = 'https://www.whed.net/results_institutions.php?Chp2=Business%20Administration'

#opening the url in browser while waiting 10 seconds for it to load
browser.get(url)
dfs = []
dfss = []
for n in range(50):
    html = browser.page_source
    soup = BeautifulSoup(html, 'lxml')

    for data in soup.find_all('p' , {'class' : 'country'}):
        item = data.text

        for thead in soup.find_all('div', {'class' : 'details'}):
            #data_2 = thead.find_all('a')
            data_2 = thead.select('h3')


            browser.find_element_by_link_text('More details').click()
            html_2 = browser.page_source
            soup_1 = BeautifulSoup(html_2, 'lxml')
            name = []
            for phone in soup_1.find_all('span' , {'class' : 'contenu'}):
                data_3 = phone.text
                name.append(data_3)
            browser.find_element_by_class_name("fancybox-item fancybox-close").click()
            dfss.append(data_2[0].text)
            dfs.append(item)

Ответы [ 3 ]

1 голос
/ 08 марта 2019

Вам не обязательно нужен селен. Вы можете использовать запросы, конечно, для большого набора результатов. Страница извлекает данные через сервер, который выполняет SQL-запрос, у которого есть параметр количества записей, который вы можете настроить для желаемого количества результатов nbr_ref_pge. Вы можете написать запрос POST, который передает необходимую информацию, которая затем передается в запрос SQL. Теперь вы можете рассчитать, как это может выглядеть в пакетах, чтобы получить общее количество, которое вам нужно, и посмотреть, есть ли смещение, чтобы учесть это.

Я не достаточно опытен с asyncio, но подозреваю, что это был бы хороший способ, так как количество запросов велико для отдельных страниц сайта. Моя попытка только с сеансом - шоу. Я взял синтаксис повторов из ответа @ datashaman

import requests
import pandas as pd
from bs4 import BeautifulSoup as bs
from requests.packages.urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter

baseUrl = 'https://www.whed.net/'
searchTerm = 'Business Administration'
headers = {'Accept': 'application/json'}
params = {'Chp2' : searchTerm}
url = 'https://www.whed.net/results_institutions.php'
data = {
    'where': "(FOS LIKE '%|" + searchTerm + "|%')",
    'requete' : '(Fields of study=' + searchTerm + ')',
    'ret' : 'home.php',
    'afftri' : 'yes',
    'stat' : 'Fields of study',
    'sort' : 'InstNameEnglish,iBranchName',
    'nbr_ref_pge' : '1000'
}

results = []

with requests.Session() as s:
    retries = Retry(total=5,
                backoff_factor=0.1,
                status_forcelist=[ 500, 502, 503, 504 ])

    s.mount('http://', HTTPAdapter(max_retries=retries))
    res = s.post(url, params = params, headers = headers, data = data)
    soup = bs(res.content, 'lxml')
    links = set([baseUrl + item['href'] for item in soup.select("[href*='detail_institution.php?']")])

    for link in links:
        res = s.get(link)  
        soup = bs(res.content, 'lxml')
        items = soup.select('#contenu span')
        name = soup.select_one('#contenu h2').text.strip()
        country = soup.select_one('.country').text.strip()
        i = 0
        for item in items:
            if 'Tel.' in item.text:
                phone = items[i+1].text
            if 'WWW:' in item.text:
                website = items[i+1].text
            i+=1
        results.append([name, country, phone, website])
        name = country = phone = website = ''
df = pd.DataFrame(results)
1 голос
/ 07 марта 2019

Если вы внимательно наблюдаете код, символ + открывает всплывающий URL-адрес.Таким образом, в этом случае вместо нажатия кнопки + и последующего обхода всплывающего окна будет легко открыть URL-адрес всплывающего окна и затем перейти по странице.Вот код для этого.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By


siteURL = "https://www.whed.net/results_institutions.php?Chp2=Business%20Administration"
browser = webdriver.Chrome(executable_path='chromedriver.exe')
browser.get((siteURL))

#this will return all the URL's of popups in an array
search = browser.find_elements_by_class_name('fancybox');
#For test purpose I used only first link
print (search[0].get_attribute("href"))
#This opens the page that comes in first pop up. Just parse the source code and get your data.
browser.get(search[0].get_attribute("href"))
#You can run a loop loop to traverse the complete array of URL's.

Чтобы получить количество URL, вы можете использовать свойство length массива.

0 голосов
/ 07 марта 2019

Для извлечения ссылок веб-сайтов университетов с веб-сайта вам не понадобятся BeautifulSoup и Selenium , которые могут легко извлечь необходимые данные, следуя приведенному ниже решению:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...