美文网首页测试开发
selenium实战-抓取百度网盘分享链接

selenium实战-抓取百度网盘分享链接

作者: 沈宥 | 来源:发表于2020-04-22 16:36 被阅读0次

    实现功能:在百度知道搜索结果中遍历,找到一个可下载的百度网盘分享链接


    B036B3B0C691096CB769331F7A690E05.gif

    1、建立一个函数,用来创建浏览器驱动

    def createDriver():
        """
        每次关闭Chromedriver后,重新创建一个
        :return:
        """
        # 创建driver,并指定Chromedriver的路径
        current_dir = os.path.abspath('.')
        chromedriverPath = os.path.join(current_dir, 'chromedriver')
        browser = webdriver.Chrome(executable_path=chromedriverPath)
    
        return browser
    

    2、启动浏览器,在主函数中完成所有功能的调用

    (1)搜索链接+关键字拼接成URL
    (2)切换到"百度知道"结果列表页
    (3)在搜索结果中遍历,列表页进入详情页,如果结果详情页中存在百度网盘分享链接,考察分享链接是否已经失效

    def getInfo(file_name, keyword):
        key_wd = {'wd': keyword}
        # URL encode
        target_url = Format_str + urllib.parse.urlencode(key_wd)
    
        # 启动浏览器
        browser = createDriver()
        browser.get(target_url)
        sleep(2)
    
        #切换到百度知道tab
        #//*[@id="s_tab"]/div/a[4]
        browser.find_element_by_xpath('//*[@id="s_tab"]/div/a[4]').click()
        sleep(2)
    
        # 搜索结果链接,第一个基本上就是百度知道的结果,所有只取第一页10条,如果搜不到直接放弃空字符
        for index in range(1, 11):
            # 获取详情页xpath
            prefix_xpath = '//*[@id="wgt-list"]/dl[' + str(index) + ']'
    
            # 判断该条搜索结果是否为百度知道
            isBaiduKown(file_name=file_name, browser=browser, prefix=prefix_xpath)
    
        # 关闭浏览器
        browser.quit()
    

    3、在结果详情页中搜索结果

    (1)确认回答总条数,以及页数
    (2)当前页只展示2条回答结果,需要判断是否打开折叠/展开按钮
    (3)最佳答案和普通答案的class_name不同,需要单独做处理
    (4)答案的Xpath中包含了用户的标识ID,所以使用class_name来定位元素

    def getResultDetail(file_name, browser):
        """
        :param browser: 浏览器
        :return: 文件百度网盘地址详情
        """
        # 回答总个数统计
        answer_number_text = browser.find_element_by_xpath('//*[@id="qb-content"]/div[2]/span[2]').get_attribute(
            'innerHTML')
        answer_number = answer_number_text.split('个')[0]
    
        # 当答案大于2个时,答案列表会折叠
        if int(answer_number) > 2:
            # 更多按钮
            more_button_xpath = '//*[@id="show-answer-hide"]'
            if isElementExist(by=By.XPATH,value=more_button_xpath,driver=browser) == True:
                # 若存在更多按钮,先按展开所有答案
                browser.find_element_by_xpath(more_button_xpath).click()
    
            # 更多折叠按钮
            more_hide_xpath = '//*[@id="wgt-answers"]/div/div[6]/div'
            if isElementExist(by=By.CLASS_NAME,value='pager-next',driver=browser) == True and int(answer_number) > 5:
                if browser.find_element_by_class_name('pager-next').is_displayed() == False:
                    browser.find_element_by_xpath(more_hide_xpath).click()
            else:
                browser.find_element_by_xpath('//*[@id="wgt-answers"]/div/div[5]/div').click()
    
            # 每页5个答案
            page_num = int(answer_number) // 5 + 1
            for page_index in range(1, page_num):
                # 获取答案详情,并判断是否有网盘下载链接
                # 最佳答案
                if page_index == 1:
                    best_answer = browser.find_element_by_class_name('best-text.mb-10').text
                    if downloadLinkObserve(file_name=file_name, detail_text=best_answer, browser=browser) == True:
                        browser.quit()
                        break
    
                # 普通答案
                nomal_answers_elements = browser.find_elements_by_class_name('answer-text.mb-10.line')
                for nomal_element in nomal_answers_elements:
                    answer_text = nomal_element.text
                    if downloadLinkObserve(file_name=file_name, detail_text=answer_text, browser=browser) == True:
                        browser.quit()
                        break
    
                # 如果有下一页,在未获取到下载链接的情况下,跳转到下一页继续
                if page_index < page_num and int(answer_number) > 5:
                    browser.find_element_by_class_name('pager-next').click()
    
        # 切换到上一页的列表
        switchWindow(browser=browser, windows_signal='current')
    

    4、提取答案文本中的分享链接

    def findUrl(string):
        """
        提取符串中URL链接
        :param string:
        :return:
        """
        # findall() 查找匹配正则表达式的字符串
        import re
    
        url = "https:" + re.match(r"[^/]+(/[^ ]*)", string).group(1)
        return url
    

    5、结果存储

    (1)将分享下载链接和提取码(如果有)分离出来,以字典的形式存储
    (2)封装数据库方法,直接调用

    def downloadLinkObserve(file_name, detail_text, browser):
        """
        检查回答中是否有百度网盘下载链接,如果有,再检查该链接分享是否已经失效
        :param detail_text:
        :param browser:
        :return:
        """
        if 'pan.baidu.com/s' in detail_text:
            download_url = findUrl(detail_text)
            download_code = ''
            if ("提取码" in detail_text):
                download_code = detail_text.split("提取码")[1]
            if (requestIsValid(url=download_url, browser=browser)) == True:
                file_link = {'download': download_url, 'code': download_code}
    
                # 更新数据库数据
                data.dbDeal.update_result(fileLink=str(file_link), fileName=file_name)
    
                return True
        else:
            return False
    

    相关文章

      网友评论

        本文标题:selenium实战-抓取百度网盘分享链接

        本文链接:https://www.haomeiwen.com/subject/etuuihtx.html