使用selenium,xpath,线程池爬取斗鱼主播信息

使用xpath,线程池爬取斗鱼主播信息:

主要爬取主播昵称,直播内容分类,房间名称,房间号以及人气,共爬取了大概110多页数据,大概15000条,保存在txt文本中,

import time

from selenium import webdriver
from  multiprocessing.dummy import Pool #导入线程池
from lxml import etree



class DouYuSpider(object):

    def __init__(self):
        self.url = "https://www.douyu.com/directory/all"
        #创建一个Chrome浏览器对象
        self.driver = webdriver.Chrome()

        # 进行计数
        self.count = 0

        #创建线程池 默认最大5个
        self.pool=Pool()



    # 解析数据
    def parse_data(self, data):
        # 1.转类型
        element = etree.HTML(data)
        # 2.解析

        # 主播昵称
        nick_name_list = element.xpath('//*[@id="listAll"]/section[2]/div[2]/ul/li/div/a[1]/div[2]/div[2]/h2/text()')

        # 直播所属分类
        category_list = element.xpath('//*[@id="listAll"]/section[2]/div[2]/ul/li/div/a[1]/div[2]/div[1]/span/text()')
        # print(category_list)

        # 主播房间名称
        room_name_list = element.xpath('//div[@class="DyListCover-info"]/h3/text()')

        # 主播房间号
        room_id_list = element.xpath('//*[@id="listAll"]/section[2]/div[2]/ul/li/div/a[2]/@href')

        # 主播人气
        hot_list = element.xpath('//*[@id="listAll"]/section[2]/div[2]/ul/li/div/a[1]/div[2]/div[2]/span/text()')

        li = []
        for nick_name, category, room_name, room_id, hot in zip(nick_name_list, category_list, room_name_list,
                                                                room_id_list, hot_list):
            s = '主播名:' + nick_name.strip() + "  " + '直播内容:' + category.strip() + "  " + '房间名称:' + room_name.strip() + "  " + '房间号:' + room_id.strip() + "  " + '人气:' + hot.strip() + "\n"
            self.count += 1
            li.append(s)

        return li



    # 保存数据
    def write_file(self, data):
        with open('douyu03.txt', 'a') as f:
            for s in data:
                f.write(s)


    def execute_request_save(self):
        # 1.获取下一页的class属性的值
        # 最后的下一页的父级li标签中的 aria-disabled=true
        # 而开始的下一页的 aria-disabled=false
        res = self.driver.find_element_by_xpath('//span[text()="下一页"]/..').get_attribute('aria-disabled')

        if res == 'false':

            # 1.1点击下一页按钮 进行翻页
            next = self.driver.find_element_by_xpath('//span[text()="下一页"]')

            time.sleep(1)
            next.click()

            # 1.2js代码 滚动到最后位置
            time.sleep(1.5)

            code_js = 'window.scrollTo(0,document.body.scrollHeight)'
            self.driver.execute_script(code_js)

            # 2.获取数据
            data = self.driver.page_source

            # 3.解析数据
            result_list = self.parse_data(data)

            # 4.保存数据
            self.write_file(result_list)



    def _callback(self, temp):
        #apply_async是异步非阻塞的
        self.pool.apply_async(self.execute_request_save, callback=self._callback)


    # 调度
    def run(self):
        #开始时间
        self.start_time=time.time()

        # 1.请求
        self.driver.get(self.url)


        # 2.获取数据
        data = self.driver.page_source

        # 3.解析数据
        result_list = self.parse_data(data)

        # 4.保存数据
        self.write_file(result_list)


        # 循环发送请求 获取所有页面的数据

        #多线程 实现异步任务
        for i in range(5):
            self.pool.apply_async(self.execute_request_save,callback=self._callback)

        #阻塞主线程  python3中主线程结束,子线程不结束。
        while True:
            #防止cpu空转
            time.sleep(0.001)
            if self.driver.find_element_by_xpath('//span[text()="下一页"]/..').get_attribute('aria-disabled')=='true':
                break


        # 关闭浏览器
        self.driver.quit()

        print('总共{}条数据'.format(self.count))
        #结束时间
        self.end_time = time.time()

        print('运行程序总共花了{}s'.format(self.end_time-self.start_time))


if __name__ == '__main__':
    DouYuSpider().run()

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值