#python #selenium #web-scraping #dynamic-tables
#питон #селен #соскабливание паутины #динамические таблицы
Вопрос:
Я пытаюсь извлечь некоторые статьи из веб-сайта, используя Selenium в Python. Однако мне очень трудно это сделать.
Пока мой код гласит:
import os 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 # Open website os.environ['PATH'] = r"C:UsersBackUp HDLAppDataLocalPrograms" driver = webdriver.Chrome() driver.get("https://watchmedier.dk/latest/filteredsitesFilter=policywatch.dkamp;sitesFilter=shippingwatch.dkamp;sitesFilter=mobilitywatch.dkamp;sitesFilter=energiwatch.dkamp;sitesFilter=finanswatch.dkamp;sitesFilter=ejendomswatch.dkamp;sitesFilter=mediawatch.dkamp;sitesFilter=agriwatch.dkamp;sitesFilter=fodevarewatch.dkamp;sitesFilter=medwatch.dkamp;sitesFilter=kapwatch.dkamp;sitesFilter=itwatch.dkamp;sitesFilter=ctwatch.dkamp;sitesFilter=watchmedier.dkamp;sitesFilter=advokatwatch.dk") # Accept cookies WebDriverWait(driver, 20).until( EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[@title='SP Consent Message']"))) WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@title='Accepter']"))).click()
Теперь я хотел бы добавить содержимое приведенной ниже таблицы в файл, т. Е. Сделать цикл, который проходит по всем страницам, и собирает информацию из «DATO», «ARTIKLE» и «SIDE» в фрейм данных. Я пытался выполнить циклы, следуя нескольким различным онлайн-руководствам, но всегда получал разные ошибки (элементы, которые невозможно найти, объекты, которые невозможно вызвать и т. Д.).
Может кто-нибудь, пожалуйста, помочь мне, как двигаться дальше?
Комментарии:
1. в URL-адресе, который вы забыли
?
после/filtered
. Для загрузки следующей страницы вы можете использовать URLamp;pageNumber=2
-адрес и т. Д. После нажатияAccpeter
вы должны перейти вparent_frame()
2. Ссылка, кажется, отключена
Ответ №1:
Если у вас были ошибки, то вы должны показать их в вопросе.
Сначала к нему нужно вернуться parent_frame()
. Но код работает и в том случае, если вы не принимаете файлы cookie.
Вы можете загружать страницы с помощью URL — адресов с "amp;pageNumber=..."
помощью-это может быть полезно, если вы хотите использовать for
-цикл для загрузки только нескольких страниц.
Чтобы загрузить все страницы, с помощью которых вы можете выполнять поиск button
, onclick="nextPage()"
и нажмите на нее. В конце концов, вы могли бы запустить непосредственно JavaScript nextPage()
для загрузки следующей страницы, но таким образом вы не знаете, есть ли кнопка для следующей страницы.
Вы можете найти все строки в таблице и использовать for
-loop для работы с каждой строкой отдельно. Вы можете использовать [1:]
, чтобы пропустить первую строку с заголовками.
В каждой строке вы можете использовать относительный xpath (начиная с точки .
) для поиска ячеек только в этой строке.
Может быть проще поместить все значения в обычный список, а затем преобразовать все в фрейм данных.
import os 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 # Open website #os.environ['PATH'] = r"C:UsersBackUp HDLAppDataLocalPrograms" #driver = webdriver.Chrome() driver = webdriver.Firefox() # --- accept (but it works also without acceptation) -- print('Load main page') url = "https://watchmedier.dk/" driver.get(url) # Accept cookies WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[@title='SP Consent Message']"))) WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@title='Accepter']"))).click() driver.switch_to.parent_frame() # --- before loops --- url = "https://watchmedier.dk/latest/filtered?sitesFilter=policywatch.dkamp;sitesFilter=shippingwatch.dkamp;sitesFilter=mobilitywatch.dkamp;sitesFilter=energiwatch.dkamp;sitesFilter=finanswatch.dkamp;sitesFilter=ejendomswatch.dkamp;sitesFilter=mediawatch.dkamp;sitesFilter=agriwatch.dkamp;sitesFilter=fodevarewatch.dkamp;sitesFilter=medwatch.dkamp;sitesFilter=kapwatch.dkamp;sitesFilter=itwatch.dkamp;sitesFilter=ctwatch.dkamp;sitesFilter=watchmedier.dkamp;sitesFilter=advokatwatch.dkamp;startDate=amp;endDate=" # load first page - if you use `while`-loop driver.get(url) all_results = [] # --- loops --- page = 1 while True: #for page in range(1, 4): print('--- page:', page, '---') # load page - if you use `for`-loop #driver.get(url "amp;pageNumber=" str(page)) # get all rows in table all_rows = driver.find_elements_by_xpath('//table[@class="c-latest-news__table"]//tr') # process all rows except first with headers for number, row in enumerate(all_rows[1:], 1): #print('row:', number) print('.', end='') # get all columns in row - relative xpath all_cells = row.find_elements_by_xpath('.//td') date = all_cells[0].text artikel = all_cells[1].find_element_by_xpath('.//a') artikel_text = artikel.text artikel_link = artikel.get_attribute('href') # count `span` and convert to `boolean` (`bool(0)` gives `False`) key = bool(len(all_cells[2].find_elements_by_xpath('.//span'))) side = all_cells[3].text # put row data in list all_results.append( [date, artikel_text, artikel_link, key, side] ) print() # find button to next page try: driver.find_element_by_xpath('//button[@onclick]').click() page = 1 except Exception as ex: print('Exception:', ex) break #if page gt; 3: break # stop `while`-loop after 3 pages # --- after loops --- import pandas as pd # convert all data to DataFrame df = pd.DataFrame(all_results, columns=['Dato', 'Artikel text', 'Artikel link', 'Key', 'Side']) print(df.to_string())
Результат: (когда я if page gt; 3: break
останавливаюсь после 3 страниц.)
Load main page --- page: 1 --- .................................................. --- page: 2 --- .................................................. --- page: 3 --- .................................................. Dato Artikel text Artikel link Key Side 0 03/12 Walgreens undersøger muligheder for salg af britisk enhed https://medwatch.dk/Medicinal___Biotek/article13527459.ece False MEDWATCH 1 03/12 FDA udvider godkendelse af Eli Lillys antistofbehandling yderligere https://medwatch.dk/Medicinal___Biotek/article13527436.ece False MEDWATCH 2 03/12 Svensk regering opgiver modstand mod EU-mindsteløn https://policywatch.dk/nyheder/eu/article13527396.ece False POLICYWATCH 3 03/12 Italien vil bruge 2,8 mia. euro til afskærmning for øgede energipriser https://energiwatch.dk/Energinyt/Politik___Markeder/article13527349.ece False ENERGIWATCH 4 03/12 Ny sms sår tvivl om topchefs forklaring om slettede sms'er https://agriwatch.dk/Nyheder/politik/article13527312.ece True AGRIWATCH 5 03/12 USA: Statsansattes iPhones ramt af hackerangreb https://itwatch.dk/ITNyt/Brancher/Sikkerhed/article13527166.ece False ITWATCH 6 03/12 Trods rekordkøb afviser A.P. Møller Holding investeringer i life science: "Et for langt skridt fra vores kompetencer i dag" https://medwatch.dk/laboratorie___diagnostik/article13525353.ece True MEDWATCH 7 03/12 3i køber AMP ud af Esvagt https://kapwatch.dk/nyheder/kapitalfonde/article13527079.ece True KAPWATCH 8 03/12 Mette F. afventer proces om slettede sms'er https://agriwatch.dk/Nyheder/politik/article13527026.ece False AGRIWATCH 9 03/12 Finanstilsynet ser særlig og sjælden kontotype skabe ny debat om negative renter https://finanswatch.dk/Finansnyt/Pengeinstitutter/article13526203.ece True FINANSWATCH 10 03/12 Vestas vælger tysk logistikpartner i Nordamerika https://energiwatch.dk/Energinyt/Renewables/article13526999.ece True ENERGIWATCH
Комментарии:
1. Большое спасибо за помощь. Код частично сработал — похоже, информация из первых 3 столбцов не сохраняется — только ссылки. Ничего, если я отправлю тебе личное сообщение?
2. когда я запускаю код, я получаю все значения из всех столбцов. Я добавляю вывод в свой ответ. Но сначала он выводит все значения в список и после создания всех страниц
DataFrame
— так что, если вы прекратите использовать кодCtrl C
, он не будет создаватьсяDataFrame
3. Спасибо за ваш ответ. Однако я снова застрял и, скорее всего, сдамся. Поэтому я хотел бы услышать, если вы, @furas, может быть, согласитесь написать код для меня (я бы, конечно, заплатил вам) или вы знаете кого-то еще, кто это сделает?
4. если у вас возникла новая проблема, создайте новый вопрос на новой странице. У вас будет место, чтобы показать все детали.
5. Я просто убежден, что сам не смогу написать код, поэтому я ищу кого-то, кто сделает это за меня (я, конечно, заплачу вам). Поэтому вместо того, чтобы создавать новый вопрос, я хотел спросить вас, как вы помогали мне раньше