首页 > 其他分享 >一个用selenium方法的爬虫案例

一个用selenium方法的爬虫案例

时间:2023-01-22 21:31:13浏览次数:50  
标签:url selenium 爬虫 detail 案例 详情页 data page browser


'''
## 爬取崔庆才老师的网站,获取电影详情页的地址、片名、类别、封面、评分、剧情
## 最后保存成一个个json文件
'''
from urllib.parse import urljoin
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
import logging
import json
from os import makedirs
from os.path import exists

# 设置无头模式
options = webdriver.ChromeOptions()
options.add_argument('--headless')

logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(levelname)s: %(message)s')
''' 定义电影列表页的地址变量, 接着定义几个常量:等待秒数、爬取页数、目录结果  '''                 
INDEX_URL = 'https://spa2.scrape.center/page/{page}'
TIME_OUT = 10
TOTAL_PAGE = 10
RESULTS_DIR = 'results'

# 定义一个模拟浏览器的webdriver对象browser,再设置等待的时间
# browser = webdriver.Chrome()
browser = webdriver.Chrome(options=options)
wait = WebDriverWait(browser, TIME_OUT)
 
''' 
1、定义一个通用的爬取网址的方法, 包含三个参数: 
   网页地址、页面加载是否成功的条件condition、以及定位器 (元组,定位节点) 
'''
def scrape_page(url, condition, locator):
    logging.info('爬取的网页地址为%s', url)
    try:
        browser.get(url)
        wait.until(condition(locator))
    except TimeoutException:
        logging.error('爬取时发生的错误信息为 %s', url, exc_info=True)

''' 
2、带入参数, 进一步爬取网址列表页的方法, 调用上面的scrape_page方法 
'''
def scrape_index(page):
    # 一个url列表页
    url = INDEX_URL.format(page=page)
    scrape_page(url, condition=EC.visibility_of_all_elements_located,
                locator=(By.CSS_SELECTOR, '#index .item'))

''' 
3、具体解析列表页内容的方法, 解析并生成详情页的URL并以完整地址返回 
'''
def parse_index():
    elements = browser.find_elements(By.CSS_SELECTOR, '#index .item .name')
    for element in elements:
        href = element.get_attribute('href')
        # 用urljoin拼接生成一个详情页地址
        yield urljoin(INDEX_URL, href)

''' 
4、定义一个通用的爬取详情页网页的方法,包含: 
   详情页地址、页面是否加载成功的condition、以及定位
   h2是页面是否加载的标志,成功就出现h2
'''
def scrape_detail(url):
    scrape_page(url, condition=EC.visibility_of_element_located,
                locator=(By.TAG_NAME, 'h2'))

''' 
5、具体解析详情页的方法,包括详情页里面各字段的节点并返回
   然后定制地址, 再用了一系列的CSS选择器,  解析各节点内容并返回
'''
def parse_detail():
    url = browser.current_url
    name = browser.find_element(By.TAG_NAME, 'h2').text
    categories = [element.text for element in browser.find_elements(
        By.CSS_SELECTOR, '.categories button span')]
    cover = browser.find_element(
        By.CSS_SELECTOR, '.cover').get_attribute('src')
    score = browser.find_element(By.CLASS_NAME, 'score').text
    drama = browser.find_element(By.CSS_SELECTOR, '.drama p').text
    # 返回内容:地址、片名、类别、封面、评分、剧情
    return {
        'url': url,
        'name': name,
        'categories': categories,
        'cover': cover,
        'score': score,
        'drama': drama
    }


''' 
6、保存方法, 保存详情页解析后的信息为json 
'''
exists(RESULTS_DIR) or makedirs(RESULTS_DIR)
def save_data(data):
    # data是字典类型,以键取值
    name = data.get('name')
    # 保存路径
    data_path = f'{RESULTS_DIR}/{name}.json'
    # 把字典类型数据,转换为json数据
    json.dump(data, open(data_path, 'w', encoding='utf-8'),
              ensure_ascii=False, indent=2)

''' 7、主运行程序,     
      把上面方法逐个调用, 从获取列表页到详情页, 
      再把详情页解析出来, 得到的字段保存'''
if __name__ == '__main__':
    try:
        for page in range(1, TOTAL_PAGE + 1):
            # 爬取一页的电影列表, 共十个
            scrape_index(page)
            # 解析出每页的详情页地址
            detail_urls = parse_index()
            # 把详情页汇总为地址列表,再遍历
            for detail_url in list(detail_urls):
                logging.info('得到详情页地址 %s', detail_url)
                scrape_detail(detail_url)
                detail_data = parse_detail()
                logging.info('详情页地址内容 %s', detail_data)
                save_data(detail_data)
    finally:
        browser.close()


标签:url,selenium,爬虫,detail,案例,详情页,data,page,browser
From: https://blog.51cto.com/u_15930659/6021571

相关文章