Как для цикла с использованием Selenium и BeautifulSoup

#python #selenium #for-loop #web-scraping #beautifulsoup

#python #селен #для цикла #очистка веб-страниц #beautifulsoup

Вопрос:

У меня есть список строк, которые я хочу повторить через цикл. Однако я не уверен, как создать цикл for для этой задачи. Функция удаляет информацию с веб-сайта. В таблицах десятки тысяч строк в зависимости от «имени». Как я могу это сделать?

У меня есть список:

 list = ['name1', 'name2', 'name3']
  

Вот мой код:

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

def get_results(search_term):
        global df
        url = "https://investor.dn.no/#!/NorgesAksjer/"       
        browser = webdriver.Chrome("C:/Users/Downloads/chromedriver.exe"))
        browser.get(url)
        search_box = browser.find_element_by_id("ar-search-input")
        search_box.send_keys(search_term)
        browser.find_element_by_css_selector(".btn.btn-lg.btn-primary").click()
        WebDriverWait(browser, 5).until(EC.element_to_be_clickable((By.LINK_TEXT, search_term))).click()
        WebDriverWait(browser, 5).until(EC.element_to_be_clickable((By.XPATH,  
                     "//*[@id='dninvestor-content']/div[1]/div/div[1]/div[2]/div[2]/div[1]/div[3]/div/div[2]/div/div[1]/a"))).click() # 
        WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, 
                     "//*[@id='dninvestor-content']/div[1]/div/div[1]/div[2]/div[2]/div[1]/div[3]/div/div[2]/div/table/tbody/tr[101]/td[1]/a"))).click() 
        time.sleep(5)
        result = []
        html = browser.page_source
        soup = BeautifulSoup(html, 'html.parser')
            for posts in soup.findAll('div',{'class':'col-xs-12 ng-scope'}):
                for tr in posts.findAll('tr')[1:]:
                    sh = [td for td in tr.stripped_strings]
                    result.append(list(sh))
                    df = pd.DataFrame(result)
        return result
  

Я хочу создать цикл for таким образом get_results(list) , чтобы:

 get_results('name1')
get_results('name2')
get_results('name3')
  

и результаты будут добавлены к df

Ответ №1:

Я бы сделал что-то вроде следующего:

 final_result = []
names = ['name1', 'name2', 'name3']
for name in names:
    final_result.append(get_results(name))
  

То, что вы делаете для преобразования в dataframe, действительно зависит от того, какую структуру вы создаете.

Если ваша функция вернула список, вы можете создать список списков в final_result, а затем использовать pd.DataFrame для преобразования в dataframe.

Комментарии:

1. Ваше решение зациклилось на списке, как я и ожидал. Однако результаты не были сохранены final_result , поскольку внутри были только NoneType s.

2. Вы добавили в свою функцию оператор return, который возвращает список?

3. Простым добавлением return result ? Я только что сделал, и ничего не изменилось.

4. Теперь поместите return result в нужное место. Я получил список списков строк. (В моем примере три списка со списками, состоящими из строк). Как мне преобразовать этот список списков строк в dataframe?

5. Используйте фрейм данных pd для результатов

Ответ №2:

 myListLen = len(list)
for i in range(0, myListLen):
  getResults(list[i])
  

Комментарии:

1. Это зациклило список, но значения не были сохранены.

2. Вам нужно вернуть данные из вашей функции, тогда код должен быть -> new_Array = [] затем внутри цикла new_Array.append(get_results(name))