Python- Selenium / BeautifulSoup PDF и скребок для таблиц

#python #selenium #web-scraping #beautifulsoup

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

Вопрос:

Я пытаюсь написать код, представляющий собой надежный веб-скребок, который можно использовать для различных ключевых слов, который в настоящее время отформатирован для поиска первого найденного PDF-файла с первой страницы поиска Google, и если он не найден, он переходит по первой ссылке поиска Google, а затем захватываетближайшая HTML-таблица и сохраняет ее в фрейме данных pandas, который позже будет отправлен в pd._to_excel, чтобы преобразовать его в файл Excel. Я задавал несколько подобных вопросов раньше, но я считаю, что у меня есть приличное количество компонентов:

 a = ["term 1", "term 2 ", "term 3"]
b = ["school 1", "school 2 ", "school 3"]
c = ["program 1", "program 2", "program 3"]



keys = []
        
for x,y,z in [(x,y,z) for x in a for y in b for z in c]:
    keys.append(z  " "  x  " "  y)
    
    
path_to_driver = r"C:wherever_you_chose_the_download_path_to_bechromedriver.exe"

download_dir = r"C:wherever_you_want_to_place_the_downloaded_filename_of_pdf_holder_file"


chrome_options = Options()
chrome_options.add_experimental_option("prefs", {
  "download.default_directory": download_dir,
  "download.prompt_for_download": False,
})
chrome_options.add_argument("--headless")
chrome_options.add_argument("--ignore-certificate-errors")
chrome_options.add_argument("--incognito")
driver = webdriver.Chrome(path_to_driver, options=chrome_options)
driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
command_result = driver.execute("send_command", params)

for k, key in enumerate(keys):
    try:
        start = time.time()
        driver.implicitly_wait(10)
        driver.get("https://www.google.com/")

        sleep_between_interactions = 5
        searchbar = driver.find_element_by_name("q")
        searchbar.send_keys(key)
        searchbar.send_keys(Keys.ARROW_DOWN)
        searchbar.send_keys(Keys.RETURN)
        pdf_element = driver.find_elements(By.XPATH, ("//a[contains(@href, '.pdf')]"))
        key_index_number = str(keys.index(key)  1 )
        key_length = str(len(keys))
        print(key_index_number   " out of "   key_length)
            
        if len(pdf_element) > 0 and  key_length < key_index_number :
            print("pdf found for: "  key)
            pdf_element[0].click()
            time.sleep(sleep_between_interactions)
            print("downloaded "   key_index_number   " out of "  str(len(keys)))
                
        elif len(pdf_element) == 0 and key_index_number != key_length:
            print("pdf NOT found for "  key)
            print(key   " pdf not downloaded, moving on...")  

            
            try:
                google_search = f"https://www.google.com/search?q={key}"
                driver.get(google_search)
                clicked_link = driver.find_element(By.XPATH, '(//h3)[1]/../../a').click()
                driver.implicitly_wait(10)
                html_source_code = driver.execute_script("return document.body.innerHTML;")
                html_soup: BeautifulSoup = BeautifulSoup(html_source_code, 'html.parser')
                url = '{}'.format(html_soup)
                r = requests.get(url)
                soup = bs(r.content, 'lxml')

                for table in soup.select('.table'):
                    tbl = pd.read_html(str(table))[0]
                    links_column = ['{}'.format(url)   i.select_one('.*')['href'] if i.select_one('.*') is not None else '' for i in table.select('td:nth-of-type(1)')]
                    tbl['Links'] = links_column
                continue
            except:
                print("something happened, probably a JS error which will be dealt with")
                continue

                
            

            
    except IndexError as index_error:
        print("Couldn't find pdf file for " """   key   """ " due to Index Error moving on....")
        print(key_index_number   " out of "   str(len(keys)))
        continue
    except NoSuchElementException:
        print("search bar didn't load, iterating next in loop")
        print(" pdf NOT found for "  key)
        print(key   " pdf not downloaded, moving on...")
        continue
    except ElementNotInteractableException:
        print("element either didn't load or doesn't exist")
        driver.get("https://www.google.com/")
        continue
  

Пока это работает нормально для поиска некоторых PDF-файлов, но не работает ни для каких таблиц, с которыми он сталкивается.

Я пробовал что-то подобное в прошлом:

              url_search = f"https://www.google.com/search?q={key}"
             request = requests.get(url_search)
             soup = BeautifulSoup(request.text, "lxml")
             first_link = soup.find("div", class_="BNeawe").text
             links_list.append(first_link) 
  

но он возвращал только список заголовков каждой ссылки без фактического перехода.

В настоящее время я также думаю о том, как хранить PDF-файлы по группам поисковых запросов.

Наконец, я пытался передать и использовать исходный код html в прошлом, но это также дало мне JavaScriptException, который, похоже, не является исключением, с которым я могу справиться должным образом в python, возможно, я что-то здесь упускаю.

Я надеюсь также, если возможно, превратить массивы a, b, c и т. Д. В input(), который можно использовать для будущего создания пользовательского интерфейса, не уверен, насколько это выполнимо в python, но стоит попробовать, если я смогу получить основную часть этогокод для работы так, как я хотел бы.

Не уверен, можно ли это сделать с помощью XPATH или селектора CSS, или как мне следует решить эту проблему, чтобы избежать проблем?

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

1. В чем именно заключается ваш вопрос / проблема?

2. Я, честно говоря, думал, что напечатал все это в качестве своего вопроса / проблемы, не уверен, что еще включить….