• 动态页面获取


    一、反爬与反反爬

    反爬措施(服务器)

    • 通过客户端请求头字段来判断是不是爬虫。
    • 通过在url中拼接加密字段,一般通过js动态生成。
    • 通过判断一个IP在一个时间段内访问频率。
    • 验证码。
    • 不直接在页面中显示数据,通过js进行数据渲染。

    反反爬措施(你)

    • 封装常用请求头,列如:user-agent,Referer。
    • 通过 js逆向,或在页面中获得加密字段,。
    • 使用IP池,设置爬取策略
    • 验证码识别
      • 字母验证码,可以通过打码平台识别/自己识别,再输入。
      • 滑动/点击验证码,可通过打码平台识别位置后,通过selenium模拟人工滑动/点击,进行验证。
    • js渲染可通过以下方法获取数据
      • 有些网站数据放置在js代码中,例如36kr。
      • 通过selenium+phantomjs(无界面浏览器)、selenium+chrome来获取数据
      • 找到数据来源的接口(ajax接口)
      • splash获取数据。Splash是一个javascript渲染服务。。
    二、ajax
    1、什么是ajax

    ​ Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。
    使用 JavaScript 向服务器提出请求并处理响应而不阻塞用户核心对象XMLHttpRequest。通过这个对象,您的 JavaScript 可在不重载页面的情况与 Web 服务器交换数据,即在不需要刷新页面的情况下,就可以产生局部刷新的效果。Ajax 在浏览器与 Web 服务器之间使用异步数据传输(HTTP 请求),这样就可使网页从服务器请求少量的信息,而不是整个页面。Ajax可使因特网应用程序更小、更快,更友好。

    总结下来:ajax是通过XMLHttpRequest对象,在不刷新页面的情况下异步发送请求,接受响应,的一种网络技术。

    三、selenium与浏览器驱动安装。
    1、安装 selenium 模块
    pip install selenium
    
    2、下载浏览器驱动并且安装。

    下载 chromedrive,首先需要查看自己的浏览器版本

    chromedrive下载地址:https://chromedriver.storage.googleapis.com/index.html?path=80.0.3987.106/

    phantomjs下载地址:https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-windows.zip

    下载完成后解压,移动到python.exe所在的目录,你也可以进行单独环境变量配置,不过这种方法是最简单的

    是否成功,在cmd命令行中输入相关命令

    四、selenium简单使用
    4.1、常用方法如下
    from selenium import webdriver
    
    chrome = webdriver.Chrome()
    
    # 访问url
    chrome.get('https://www.baidu.com')
    
    # 元素选择
    input_1 = chrome.find_element_by_id('kw')  # 通过id选择
    input_2 = chrome.find_element_by_xpath("//input[@id='su']")  # 通过xpath
    input_3 = chrome.find_element_by_css_selector('#su')  # 通过css选择器
    input_4 = chrome.find_element_by_class_name('bg s_btn')  # 通过类名
    
    # 往输入框内发送内容,并且点击
    input_1.send_keys('spider')
    button = chrome.find_element_by_xpath('//input[@id="su"]')
    
    # 获取某对象的png bytes数据
    content_bytes = button.screenshot_as_png
    
    # 获取元素的位置
    print(button.location)
    button.click()
    
    # 全屏截图
    chrome.save_screenshot('1.png')
    
    # 元素大小
    print(button.size)
    chrome.close()
    
    # 关闭选项卡
    chrome.close()
    
    # 退出浏览器
    chrome.quit()
    
    
    4.2、selenium提取cookies字典
    from selenium import webdriver
    
    chrome = webdriver.Chrome()
    chrome.get('http://www.baidu.com')
    
    cookies = chrome.get_cookies()
    
    cok_dic = {i.get('name'): i.get('value') for i in cookies}
    print(cok_dic)
    
    chrome.close()
    chrome.quit()
    
    4.3、selenium中的三种等待

    代码执行的速度是非常快的,但是我们通过selenium+浏览器驱动去驱动一个浏览器执行某些动作,但是浏览器执行的速度很慢。我们进行数据提取时,浏览器页面并没有加载完毕,我们可能会提取不到数据,所以需要设置等待。

    强制等待:shitime.sleep(1) #程序暂停1秒
    隐式等待:chrome.implicitly_wait(5) #最多等待5秒,在5秒内,加载完成就不会报错。
    显示等待:指定时间情况下,指定某些元素或者状态是否加载完成。加载完成就不会报错。
    
    from selenium.webdriver.common.by import By #通过什么方式判断:id、xpath、cssselect、等
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    next_page = WebDriverWait(self.browser, 5).until(
                    EC.presence_of_element_located((By.XPATH, '//div[contains(@class,"paginator")]/a[last()]'))) #等待a标签是否加载成功。
                next_url = next_page.get_attribute('href')
                
    #EC这个类中提供了很多判断条件,下面是常用判断条件
    title_is    #title标签内容是..
    title_contains #title标签包含。
    presence_of_element_located  #元素加载完成
    visibility_of_element_located  #元素可视
    text_to_be_present_in_element #元素内的内容加载完成
    element_to_be_clickable  #元素可点击
    element_to_be_selected  #元素可选择
    

    五、相关案例

    5.1、豆瓣图书
    from selenium import webdriver
    import time
    import random
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from lxml import etree
    import xlwt
    
    
    class Douband():
        def __init__(self, kw, page):
            self.base_url = 'https://book.douban.com/'
            self.browser = webdriver.Chrome()
            self.page_url = ''
            self.kw = kw
            self.page = page
            self.cont_list = []
    
        def get_index(self, url):
            self.browser.get(url)
            try:
                next_page = WebDriverWait(self.browser, 5).until(
                    EC.presence_of_element_located((By.XPATH, '//div[contains(@class,"paginator")]/a[last()]')))
                next_url = next_page.get_attribute('href')
                self.page_url = next_url
                return self.browser.page_source
            except Exception:
                self.browser.quit()
    
        def parser_index(self, content):
            html = etree.HTML(content)
            item_list = html.xpath('//div[contains(@class,"sc-bZQynM" )]')
            for item in item_list:
                title = item.xpath('.//div[@class="detail"]/div[@class="title"]/a/text()')
                rating = item.xpath('.//div[@class="detail"]/div[contains(@class,"rating")]/span[2]/text()')
                times = item.xpath('.//div[@class="detail"]/div[contains(@class,"rating")]/span[3]/text()'),
                info = item.xpath('.//div[@class="detail"]/div[@class="meta abstract"]/text()'),
                item = {
                    'title': title[0] if title else None,
                    'rating': rating[0] if rating else None,
                    'times': times[0] if times else None,
                    'info': info[0] if info else None,
                }
                print(item)
                self.cont_list.append(item)
    
        def search(self):
            self.browser.get(self.base_url)
            self.browser.find_element_by_id('inp-query').send_keys(self.kw)
            time.sleep(random.random())
            self.browser.find_element_by_xpath('//div[@class="inp-btn"]/input').click()
    
        def write_to_excel(self, filename, sheetname):
            # 创建workbook
            file = xlwt.Workbook()
    
            # 添加sheet表
            sheet = file.add_sheet(sheetname)
    
            # 设置表头
            head = [i for i in self.cont_list[0].keys()]
            for i in range(len(head)):
                sheet.write(0, i, head[i])
            # 写内容
            i = 1
            for item in self.cont_list:
                for j in range(len(head)):
                    sheet.write(i, j, item[head[j]])
                i += 1
            # 保存
            file.save(filename)
            print('写入excle成功!')
    
        def run(self):
            self.search()
            count = 0
            self.page_url = self.browser.current_url
            while count < self.page:
                content = self.get_index(self.page_url)
                self.parser_index(content)
                count += 1
            self.browser.quit()
            self.write_to_excel('python.xls', 'book')
    
    
    if __name__ == '__main__':
        db = Douband('python', 10)
        db.run()
    
    5.2、腾讯招聘
    import requests
    from jsonpath import jsonpath
    from excle_wirte import ExcelUtils
    import os
    
    
    def get_content(url):
        headers = {
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
            'referer': 'https://careers.tencent.com/search.html'
        }
    
        res = requests.get(url, headers=headers).json()
        jp = jsonpath(res, '$.*.Posts.*')
        print(jp)
        return jp
    
    
    def write_excel(filename, item_list, sheetname):
        if not os.path.exists(filename):
            ExcelUtils.write_to_excel(filename, item_list, sheetname)
        else:
            ExcelUtils.append_to_excel(filename, item_list)
    
    
    if __name__ == '__main__':
        base_url = 'https://careers.tencent.com/tencentcareer/api/post/Query?timestamp=1585401795646&countryId=&cityId=&bgIds=&productId=&categoryId=&parentCategoryId=&attrId=&keyword=&pageIndex={}&pageSize=20&language=zh-cn&area=cn'
        for i in range(1, 11):
            content = get_content(base_url.format(i))
            write_excel('tencent.xls',content,'hr')
    
    在这里用到了写入excel的一些方法,我这里直接引用了别人封装的方法。
    import xlwt
    import xlrd
    from xlutils.copy import copy as C
    
    
    class ExcelUtils(object):
        @staticmethod
        def write_to_excel(filename, item_list, sheetname):
            try:
                # 创建workbook
                workbook = xlwt.Workbook(encoding='utf-8')
                # 给工作表添加sheet表单
                sheet = workbook.add_sheet(sheetname)
                # 设置表头
                head = []
                for i in item_list[0].keys():
                    head.append(i)
                # print(head)
                # 将表头写入excel
                for i in range(len(head)):
                    sheet.write(0, i, head[i])
                # 写内容
                i = 1
                for item in item_list:
                    for j in range(len(head)):
                        sheet.write(i, j, item[head[j]])
                    i += 1
                # 保存
                workbook.save(filename)
                print('写入excle成功!')
            except Exception as e:
                print(e)
                print('写入失败!')
    
        @staticmethod
        def append_to_excel(filename, item_list):
            # 打开excle文件
            work_book = xlrd.open_workbook(filename)
            # 获取工作表中的所有sheet表单名称
            sheets = work_book.sheet_names()
            # 获取第一个表单
            work_sheet = work_book.sheet_by_name(sheets[0])
            # 获取已经写入的行数
            old_rows = work_sheet.nrows
            # 获取表头的所有字段
            keys = work_sheet.row_values(0)
            # 将xlrd对象转化成xlwt,为了写入
            new_work_book = C(work_book)
            # 获取表单来添加数据
            new_sheet = new_work_book.get_sheet(0)
            i = old_rows
            for item in item_list:
                for j in range(len(keys)):
                    new_sheet.write(i, j, item[keys[j]])
                i += 1
    
            new_work_book.save(filename)
            print('追加成功!')
    
  • 相关阅读:
    C#自定义控件的开发:Pin和Connector
    C# 调用第三方DLL完整实例
    利用微软Speech SDK 5.1开发语音识别系统主要步骤
    如何在Android中使用OpenCV
    VS 2012单元测试和测试资源管理器
    .NET Reflector插件FileDisassembler还原源码
    根据powerdesigner的OO模型生成C#代码
    SQLServer2008设置开启INTERNET远程连接
    Kudu-压缩
    kudu的读取数据流程
  • 原文地址:https://www.cnblogs.com/hjnzs/p/12596120.html
Copyright © 2020-2023  润新知