python - 使用 selenium 和 bs4 进行网页抓取

标签 python html web-scraping beautifulsoup selenium-chromedriver

我正在尝试基于该页面的网络抓取构建一个数据框

https://www.schoolholidayseurope.eu/choose-a-country

html first 我对 selenium 说点击我选择的页面然后我为构建标题和正文放置 xpath 和标签元素但是我没有我想要的格式我的元素是 NaN 或重复。

按照我的脚本:

def get_browser(url_selector):
    """Get the browser (a "driver")."""
    #option = webdriver.ChromeOptions()
    #option.add_argument(' — incognito')
    path_to_chromedriver = r"C:/Users/xxxxx/Downloads/chromedriver_win32/chromedriver.exe"
    browser = webdriver.Chrome(executable_path= path_to_chromedriver)
    browser.get(url_selector)
    
    """ Try with Italie"""
    browser.find_element_by_xpath(italie_buton_xpath).click()

    """ Raise exception : down browser if loading take more than 45sec : timer is the logo website as a flag"""
    # Wait 45 seconds for page to load
    timeout = 45
    try:
        WebDriverWait(browser, timeout).until(EC.visibility_of_element_located((By.XPATH, '//*[@id="s5_logo_wrap"]/img')))
    except TimeoutException:
        print("Timed out waiting for page to load")
        browser.quit()
    return browser

browser = get_browser(url_selector)
headers = browser.find_element_by_xpath('//*[@id="s5_component_wrap_inner"]/main/div[2]/div[2]/div[3]/table/thead').find_elements_by_tag_name('tr')                                                            
headings = [i.text.strip() for i in headers]
bs_obj = BeautifulSoup(browser.page_source, 'html.parser')
rows = bs_obj.find_all('table')[0].find('tbody').find_all('tr')[1:]
table = []

for row in rows : 
    line = next(td.get_text() for td in row.find_all("td"))
    print(line)
    table.append(line)
browser.quit()
    
pd.DataFrame(line, columns = headings)

返回

单列数据框,如:

    School Holiday Region Start date End date Week
0   Easter holidays 2018
1   REMARK: Small differences by region are possi...
2   Summer holiday 2018
3   REMARK: First region through to last region.
4   Christmas holiday 2018

存在三个问题,我不希望 REMARK 行和学校假期开始日期和结束日期被视为单独的单词,并且整个数据帧未拆分。

如果我拆分我的标题并勾勒出两者不匹配的形状 由于 REMARKS 行,我在列表中得到了 9 个元素而不是 3 个,并且由于分隔的单词,我在标题中得到了 8 个元素而不是 5 个。

最佳答案

你可以找到主页上的所有链接,然后用 selenium 遍历每个 url:

from selenium import webdriver
from bs4 import BeautifulSoup as soup
import re, contextlib, pandas
d = webdriver.Chrome('/Users/jamespetullo/Downloads/chromedriver')
d.get('https://www.schoolholidayseurope.eu/choose-a-country')
_, *countries = [(lambda x:[x.text, x['href']])(i.find('a')) for i in soup(d.page_source, 'html.parser').find_all('li', {'class':re.compile('item\d+$')})]
@contextlib.contextmanager
def get_table(source:str):
   yield [[[i.text for i in c.find_all('th')], [i.text for i in c.find_all('td')]] for c in soup(source, 'html.parser').find('table', {'class':'zebra'}).find_all('tr')]
results = {}
for country, url in countries:
  d.get(f'https://www.schoolholidayseurope.eu{url}')
  with get_table(d.page_source) as source:
     results[country] = source

def clean_results(_data):
  [headers, _], *data = _data
  return [dict(zip(headers, i)) for _, i in data]

final_countries = {a:clean_results(b) for a, b in results.items()}

关于python - 使用 selenium 和 bs4 进行网页抓取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52217866/

相关文章:

Python 2.6 : Process local storage while using multiprocessing. 池

javascript - 导航栏上的 2 个导航按钮(引导移动设备)

python - 使用 BeautifulSoup 进行网页抓取(Jupyter Notebook)

python - 如何并发多次运行相同的异步函数?

python - Python如何访问socket()等OS API函数?

python - pygame 在矩形消失后不会重新绘制矩形

html - 如何链接仅影响 1 个 div 且不影响所有其他 div 的外部 css 文件

html - 使用 fontawesome 图标作为 <img> 的替代文本

python - 如何使用 Beautifulsoup 基于嵌套标签来切片和重新组合文本?

Python:AttributeError: 'Response'对象没有属性 'read'