第五讲案例

驱动浏览器获取豆瓣评书内容

首先百度豆瓣读书,进入官网,搜索python使用开发者工具进行操作。https://search.douban.com/book/subject_search?search_text=python&cat=1001&start=%s
要求获取每一页的python读物的信息
在这里插入图片描述
这里我们并不知道一共有多少页,可以使用while循环条件判断,当获取的读物的内容列表为空时代表结束。
1、导包,需要驱动、强制等待、截取等操作,因此需要导入下列三个包,可以用的时候再导:

from selenium import webdriver
from lxml import etree
import time

2、在程序入口创建driver对象

if __name__ == '__main__':
    # dirver一般要放在全局变量中,不能放在方法中
    # 1、创建浏览器驱动对象
    driver = webdriver.Chrome()
    main()

3、循环请求每一页,获取内容并创建xpath对象。

def get_content(url):
    """获取内容,返回xpath对象"""
    # 请求url
    driver.get(url)
    # 等待1秒
    time.sleep(1)
    # 获取页面源代码
    return etree.HTML(driver.page_source)

其余内容可参考以下代码,若有疑惑的地方可相应的参考前几讲:

"""
驱动浏览器打开页面获取豆瓣评书内容
"""
from selenium import webdriver
from lxml import etree
import time


def get_content(url):
    """获取内容,返回xpath对象"""
    # 请求url
    driver.get(url)
    # 等待1秒
    time.sleep(1)
    # 获取页面源代码
    return etree.HTML(driver.page_source)


def content_none(lst):
    """将缺失的数据补为无,防止报错"""
    if not lst:
        lst = ['无']
    return lst[0]


def get_info(book_e_list):
    """使用xpath截取内容并保存到字典中, """
    for book in book_e_list:
        info_dict = dict()
        title = content_none(book.xpath('.//div[@class="title"]/a/text()'))
        url = content_none(book.xpath('.//div[@class="title"]/a/@href'))
        score = content_none(book.xpath('.//span[@class="rating_nums"]/text()'))
        p_num = content_none(book.xpath('.//span[@class="pl"]/text()'))
        infos = book.xpath('.//div[@class="meta abstract"]/text()')
        if infos:
            # print(title, url, score, p_num, infos)
            print(infos)
            # 该信息以/分割,可以使用字符串方法切割为列表数据
            info_list = infos[0].split(r'/')
            try:
                author = info_list[0]
                price = info_list[-1]
                time = info_list[-2]
                info_dict['title'] = title
                info_dict['url'] = url
                info_dict['score'] = score
                info_dict['p_num'] = p_num
                info_dict['author'] = author
                info_dict['price'] = price
                info_dict['time'] = time
                print(info_dict)
            except Exception:
                pass


def main():
    """豆瓣评书爬取主线"""
    # while循环获取分页
    page = 1
    while True:
        base_url = 'https://search.douban.com/book/subject_search?search_text=python&cat=1001&start=%s'
        page_content = get_content(base_url % (page-1)*15)
        # print(page_content)
        # xpath截取页面内容
        book_e_list = page_content.xpath('//div[@id="root"]/div/div[2]/div/div/div[position()>1]')
        # print(book_e_list)
        if not book_e_list:
            break
        # 获取并保存数据
        get_info(book_e_list)
        # 测试  基本一页对其余页都对,设置堵塞方便查看数据
        # time.sleep(10000)
        page += 1


if __name__ == '__main__':
    # dirver一般要放在全局变量中,不能放在方法中
    # 1、创建浏览器驱动对象
    driver = webdriver.Chrome()
    main()

LOL斗鱼直播间信息

百度搜索斗鱼直播,任选一个分类,案例中选择爬取LOL直播间信息:https://www.douyu.com/g_LOL
该案例旨在实践使用selenium操作页面元素,更多方法使用请百度“selenuim常用方法总结”。作为一个初学者,接触到的操作方法并不全面,请见谅。
第一个要点是判断是否可以点击下一页:
在这里插入图片描述
在最后一页的下一页按钮:
在这里插入图片描述
因此可以看出判断是否下一页只需拿到li标签中的aria-disabled值即可
这里我们先要拿到“下一页”这个页面元素,可以使用xpath,页可以学一下如何使用class获取:
代码提示有两个相似的find_elements_by_class_name、find_element_by_class_name,当class值有两个以上时使用第一个,否则会报错。

next_page = driver.find_elements_by_class_name(' dy-Pagination-next')[-1]

获取属性的属性值,可以使用元素的get_attribute方法

next_page.get_attribute('aria-disabled')

完整代码如下:

import time
from selenium import webdriver
from lxml import etree


def content_none(lst):
    """如果为空则复制为无"""
    if not lst:
        lst = ['无']
    return lst[0]


def get_content(li_list):
    """获取并保存直播间信息"""
    for li in li_list:
        room_dict = dict()
        title = content_none(li.xpath('.//h3[@class="DyListCover-intro"]/text()'))
        author = content_none(li.xpath('.//h2[@class="DyListCover-user"]/text()'))
        room_dict['title'] = title
        room_dict['author'] = author
        print(room_dict)


def main():
    """
    爬取斗鱼直播间数据
    :return:
    """
    # url
    url = 'https://www.douyu.com/g_LOL'
    # 等待
    time.sleep(1)
    # 发送请求
    driver.get(url)
    time.sleep(1)
    # 循环进入下一页
    while True:
        # 如果class的值相同的不止一个元素则要用elements,因此一般用xpath
        next_page = driver.find_elements_by_class_name(' dy-Pagination-next')[-1]
        tree = etree.HTML(driver.page_source)
        li_list = tree.xpath('//ul[@class="layout-Cover-list"]/li')
        get_content(li_list)

        # 判断是否有下一页
        if next_page.get_attribute('aria-disabled'):
            break
        # 进入下一页
        next_page.click()
        # 测试
        # time.sleep(1000)


if __name__ == '__main__':
    # 创建驱动对象
    driver = webdriver.Chrome()
    main()

豆瓣电影

百度豆瓣电影,https://movie.douban.com/chart
获取右侧全部分类:
在这里插入图片描述
循环请求每一类。
随便进入一个类别页面,通过开发者工具查找数据位置,下滑页面,可以通过XHR获取保存数据的响应文件:
在这里插入图片描述
观察该文件的url可以较容易的得到文件url的变化规律
在这里插入图片描述

import requests, re
from lxml import etree
import os


def get_xpath(url):
    """"""
    response = requests.get(url, headers=headers)
    return etree.HTML(response.text)


def get_type(url):
    """"""
    content = get_xpath(url)
    type_list_e = content.xpath('//div[@class="types"]/span/a/@href')
    move_type = list()
    for typ in type_list_e:
        move_type.append(re.search(r'&type=(\d+)&interval_id',typ).group(1))
    # print(move_type)
    return move_type


def get_json(move_type):
    """

    :param move_type:
    :return:
    """
    url = 'https://movie.douban.com/j/chart/top_list?'
    page = 0
    while True:
        params = {
            'type': move_type,
            'interval_id': '100:90',
            'action': '',
            'start': str(page*20),
            'limit': '20'
        }
        headers.update({'X-Requested-With': 'XMLHttpRequest'})
        response = requests.get(url, headers=headers, params=params)
        # print(response.json())
        infos = response.json()
        from day_4.Excel_Utils.excel_utiles import ExcelUtils
        if os.path.exists(filename):
            ExcelUtils.append_to_excel(infos, filename)
        else:
            ExcelUtils.write_to_excel(infos, filename)
        page += 1
        if response.json() == '[]':
            break


def main():
    """

    :return:
    """
    # 1、请求首页,获取电影类型type值
    base_url = 'https://movie.douban.com/chart'
    move_type_list = get_type(base_url)
    for move_type in move_type_list:
        # 获取json数据进行保存
        get_json(move_type)


if __name__ == '__main__':
    filename = '电影.xls'
    # 定义通用请求头,可以更新
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
    }
    main()
    

该案例较为简单,读者可以练习下文件注释,有助于梳理爬取思路。

感谢各位的耐心阅读,有错误欢迎批评指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值