• 爬虫过程和反爬


    爬虫过程

    爬虫:获取网络数据(公开的网络)
    
    网络数据来源:网站对应的网页、手机APP
    
    • 1
    • 2
    • 3

    一、获取网络数据(requests、selenium)

    1.requests

    • 定义

      Python获取网络数据的第三方库(基于http或https协议的网络请求)
      
      • 1
    • 应用场景

      1)直接请求网页地址
      2)对提供网页数据的数据接口发送请求
      
      • 1
      • 2
    • 基本用法

      1)对目标网页直接发送请求: 
      requests.get(网页地址):获取指定页面的数据返回一个响应对象
      2)获取响应的状态码:response.status_code
      3)获取响应头:response.headers
      4)请求内容(返回的有效数据):
      a.response.content: 二进制类型的数据(图片、视频、音频等,例如:图片下载)
      b.response.text: 字符串类型的数据(网页)
      c.response.json(): 对请求内容做完json解析后的数据(json数据接口)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      response = requests.get('https://cd.zu.ke.com/zufang')
      print(response)    # 200表示请求成功
      
      • 1
      • 2
    • 设置cookie
      自动登录原理:人工在浏览器上完成登录操作,获取登录后的cookie信息(登录信息),再通过代码发送请求的时候携带登录后的cookie。
      在这里插入图片描述

      import requests
      
      headers = {
          'cookie': '复制到的cookie值',
          'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
      }
      
      response = requests.get('https://www.zhihu.com/', headers=headers)
      print(response.text)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 代理IP
      ❀获取代理IP(可能需要花钱买)

      首先需要去代理IP网页获取一个代理IP:极光代理IP- https://www.jghttp.com/
      
      • 1

      ❀使用代理IP的语法:

      1.创建代理对应的字典
      # 方法1
      proxies = {
         'http': '221.10.105.215:4531',
      	'https': '221.10.105.215:4531'
      }
      
      # 方法2
      proxies = {
        'http': 'http://221.10.105.215:4531',
        'https': 'http://221.10.105.215:4531'
      }
      response = requests.get(需要获取信息的网址, headers=headers, proxies=proxies)
      print(response.text)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      完整代码:

      import requests
      
      headers = {
      	 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
      }
      
      # 1.创建代理对应的字典
      # 方法1
      proxies = {
      	 'http': '221.10.105.215:4531',
      	 'https': '221.10.105.215:4531'
      }
      
      # 方法2
      # proxies = {
       #     'http': 'http://221.10.105.215:4531',
      #     'https': 'http://221.10.105.215:4531'
      # }
      response = requests.get('https://movie.douban.com/top250', headers=headers, proxies=proxies)
       print(response.text)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20

    2.selenium

    • 安装第三方模块:selenium
      ❀使用pycharm安装,file->settings->project->点击里面模块右边的加号安装
      ❀或者直接在teiminal里输入 pip(3) install requests

    • 下载驱动器

      1)查看浏览器版本:chrome://version/

      2)chromedriver国内镜像:https://registry.npmmirror.com/binary.html?path=chromedriver/0

      3)到与浏览器最接近的文件夹进去下载,最新的是104.0.5112.81
      在这里插入图片描述

      在这里插入图片描述

      4)将下载好压缩包解压移动到python环境安装目录里。

      在pycharm里面的settings里面查找环境目录,将解压好的chromedriver.exe放在python.exe同一目录。
      
      • 1

      在这里插入图片描述

    • 获取网页数据

      1.创建浏览器对象(浏览器对象如果是全局变量,浏览器不会自动关闭)
      2.打开网页
      3.获取网页源代码
      4.关闭浏览器
      
      • 1
      • 2
      • 3
      • 4
      # 导入模块
      from selenium.webdriver import Chrome
      
      # 1.创建浏览器对象
      b = Chrome()
      # 2.打开网页
      b.get('https://movie.douban.com/top250')
      # 3.获取网页源代码: b.page_source
      print(b.page_source)
      # 4.关闭浏览器
      b.close()
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 控制浏览器基础操作

      1.输入框输入内容
      第一步:找到输入框
      第二步:输入框输入内容-传值(标签.send_keys)
      2.点击按钮
      第一步:找到需要点击的标签
      第二步:点击(标签.click())
      3.切换选项卡
      1)获取当前浏览器上所有的窗口(选项卡):b.window_handles
      2)切换选项卡:b.switch_to.window(切换到的窗口)
      注意:selenium中,浏览器对象默认指向一开始打开的选项卡。除非用代码切换,否则浏览器对象指向的选项卡不会切换
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      # 1.输入框输入内容
      # 1)找到输入框
      input_tag = b.find_element_by_id('key')
      # 2)输入框输入内容
      input_tag.send_keys('电脑\n')
      
      • 1
      • 2
      • 3
      • 4
      • 5
      # 2.点击按钮
      # 1)找到需要点击的标签
      btn = b.find_element_by_css_selector('#navitems-group2 .b')
      # 2)点击标签
      btn.click()
      
      • 1
      • 2
      • 3
      • 4
      • 5
      # 3.切换选项卡
      # 进入中国知网输入‘数据分析’之后利用切换选项卡获取每篇论文的摘要
      
      from selenium.webdriver import Chrome
      from time import sleep
      from bs4 import BeautifulSoup
      
      # 1.基本操作
      b = Chrome()    # 创建浏览器对象
      b.get('https://www.cnki.net/')    # 打开中国知网
      
      # 获取输入框并输入内容
      search_tag = b.find_element_by_id('txt_SearchText')
      search_tag.send_keys('数据分析\n')
      sleep(4)      # 切换界面等待一会
      
      # 获取需要点击的所有标签:如果拿到标签后需要点击或者输入,必须通过浏览器对象获取标签
      results = b.find_elements_by_css_selector('.result-table-list .name>a')
      
      for i in range(len(results)):
          # 点击第一个结果(这会打开新的选项卡)
          results[i].click()
          b.switch_to.window(b.window_handles[-1])   # 切换选项卡到点开的论文窗口
      
          # 解析内容
          soup = BeautifulSoup(b.page_source, 'lxml')
          result = soup.select_one('#ChDivSummary')    # 获取摘要
          # 没有摘要输出无
          if not result:
              print('无')
          else:
              print(result.text)
              
          b.close()    # 关闭当前指向的窗口(最后一个窗口),窗口关闭后,浏览器对象的指向不会改变。
          sleep(2)
          
          # 回到第一个窗口点击下一个搜索结果
          b.switch_to.window(b.window_handles[0])    # 切换到第一个页面
      
      b.close()   # 关闭浏览器
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
    • 页面滚动

      语法:
      window.scrollBy(x方向偏移量,y方向偏移量)
      执行滚动操作 - 执行js中的滚动代码: 
      
      • 1
      • 2
      • 3
      for x in range(10):
      	b.execute_script('window.scrollBy(0,800)')
      	sleep(1)
      
      • 1
      • 2
      • 3

      需要等页面滚动之后把信息加载完才能解析数据,否则数据可能不完整。

    • 设置cookie

      ❀获取cookie

      第一步:打开需要完成自动登录的网站(需要获取cookie的网站)
      第二步:给足够长的时间让人工完成自动登录并且刷新出登录后的页面
      	   注意:一定要将第一个页面刷新出登录后的状态!!!
      第三步:获取登陆后的cookie并将其保存在本地文件中
      	   get_cookies()
      
      • 1
      • 2
      • 3
      • 4
      • 5
      from selenium.webdriver import Chrome
      from json import dumps
      
      b = Chrome()
      
      # 1.打开需要完成自动登录的网站(需要获取cookie的网站)
      b.get('https://www.taobao.com/')
      
      # 2.给足够长的时间让人工完成自动登录并且刷新出登录后的页面
      # 一定要将第一个页面刷新出登录后的状态。
      input('已经完成登录:')
      
      # 3.获取登陆后的cookie并将其保存在本地文件中
      cookies = b.get_cookies()
      print(cookies)
      
      with open('files/taobao.txt', 'w', encoding='utf-8') as f:
          f.write(dumps(cookies))    # 将获取的cookie转换成json写入文件。
      print('写入完成!')
      
      b.close()
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21

      ❀使用cookie

      第一步:打开需要完成自动登录的网站(需要获取cookie的网站)
      第二步:从文件读出数据添加cookie
      第三步:重新打开需要登录的网页
      
      • 1
      • 2
      • 3
      from selenium.webdriver import Chrome
      from json import loads
      b = Chrome()
      
      # 1.打开需要完成自动登录的网站(需要获取cookie的网站)
      b.get('https://www.taobao.com/')
      
      # 2.从文件读出数据添加cookie
      with open('files/taobao.txt', encoding='utf-8') as f:
          content = f.read()
          cookies = loads(content)   # 将json数据转换成python格式
      
      for x in cookies:
          b.add_cookie(x)
      
      # 3.重新打开需要登录的网页
      b.get('https://www.taobao.com/')
      
      input('结束')
      b.close()
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
    • 代理IP

      ❀导入相关模块

      from selenium.webdriver import Chrome, ChromeOptions
      
      • 1

      ❀创建配置对象

      options = ChromeOptions
      
      • 1

      ❀添加配置

      options.add_argument('--proxy-server=http://ip')
      
      • 1

      ❀通过指定配置创建浏览器对象

      b = Chrome(options=options)
      
      • 1

      ❀通过浏览器对象获取网页

      b.get('https://movie.douban.com/topp250')
      
      • 1

      ❀完整代码

      from selenium.webdriver import Chrome, ChromeOptions
      
      # 1.创建配置对象
      options = ChromeOptions
      # 2.添加配置
      options.add_argument('--proxy-server=http://ip')
      # 3.通过指定配置创建浏览器对象
      b = Chrome(options=options)
      
      b.get('https://movie.douban.com/topp250')   # 网址是被封了的
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    • 基本配置

      ❀配置前需要自己创建配置对象

      from selenium.webdriver import ChromeOptions, Chrome
      options = ChromeOptions()
      
      • 1
      • 2

      ❀取消设置环境提示

      # 固定写法,有需要可添加快捷导入
      options.add_experimental_option('excludeSwitches', ['enable-automation'])
      
      • 1
      • 2

      ❀设置取消图片加载—加快运行速度

      # 固定写法,需要添加快捷导入
      options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
      
      • 1
      • 2

      ❀通过浏览器对象获取网页

      b = Chrome(options=options)
      b.get('https://www.jd.com')
      
      • 1
      • 2

      ❀完整代码

      from selenium.webdriver import ChromeOptions, Chrome
      
      options = ChromeOptions()
      # 1.取消设置环境提示
      options.add_experimental_option('excludeSwitches', ['enable-automation'])
      
      # 2.设置取消图片加载
      options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
      
      b = Chrome(options=options)
      b.get('https://www.jd.com')
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 等待

      ❀隐式等待: implicitly_wait(时间(秒))

      a.没有设置隐式等待:在通过浏览器获取标签时,如果标签不存在会直接报错;
      b.设置了隐式等待:在通过浏览器获取标签时,如果标签不存在不会直接报错,不会马上报错,而是在指定时间范围内不断尝试重新获取标签,直到获取到标签或者超时为止(超时会报错);
      c.一个浏览器只需设置一次隐式等待时间,它会作用于这个浏览器每次获取标签的时候。
      
      • 1
      • 2
      • 3
      from selenium.webdriver import ChromeOptions, Chrome
      
      options = ChromeOptions()
      # 1.取消设置环境提示
      options.add_experimental_option('excludeSwitches', ['enable-automation'])
      # 2.设置取消图片加载
      options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
      
      b = Chrome(options=options)
      b.get('https://www.jd.com')
      
      # 设置隐式等待时间,获取标签时才有效
      b.implicitly_wait(5)
      print('------')
      
      input_tag = b.find_element_by_id('key')
      input_tag.send_keys('钱包\n')
      
      b.close()
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19

      ❀显式等待:等待某个条件成立或者不成立为止

      1)创建等待对象:WebDriverWait(浏览器对象,超时时间)
      2)添加等待条件:
      等待对象.until(条件)  -  等到条件成立为止
      等待对象.until_not(条件)  -  等到条件不成立为止
      
      条件写法:
      presence_of_element_located(标签)    -   指定标签出现
      text_to_be_present_in_element(标签, 值)   -   指定标签的value属性中包含指定值
      text_to_be_present_in_element_value(标签, 值)  -  指定标签的标签内容中包含指定值
      
      注意:条件中提供标签的方式
      By.xxx(xxx)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      from selenium.webdriver.support.ui import  WebDriverWait
      from selenium.webdriver.support import  expected_conditions as EC
      from selenium.webdriver.common.by import By
      
      options = ChromeOptions()
      # 1.取消设置环境提示
      options.add_experimental_option('excludeSwitches', ['enable-automation'])
      # 2.设置取消图片加载
      options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
      
      b = Chrome(options=options)
      b.get('https://www.jd.com')
      
      wait = WebDriverWait(b, 10)    # 创建
      wait.until(EC.text_to_be_present_in_element_value(By.ID, 'key'), '电脑')
      print(b.page_source)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16

    3.常见反爬

    • 浏览器伪装

      import requests
      
      headers = {
              'user-agent': 自己电脑浏览器信息
      }
      
      response = requests.get('https://movie.douban.com/top250', headers=headers)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • 登录反爬

      解决办法:
      设置cookie
      requests和selenium里分别写了
      
      • 1
      • 2
      • 3
    • 代理IP

      requests和selenium里分别写了
      
      • 1

    4.找数据接口

    • 第一步:打开控制台

      在这里插入图片描述

    • 第二步:

      在这里插入图片描述

    • 第三步:

      在这里插入图片描述

    二、解析数据(从获取到的网络数据中提取有效数据)

    1.正则表达式

    # 例子
    # 名字里面有换行,用单行匹配(?s)
    names = findall(r'(?s)(.+?)', result)
    
    • 1
    • 2
    • 3

    2.基于css选择器的解析器(bs4

    • bs4的作用

      专门用来解析网页数据的第三方库。(基于css选择器解析网页数据)
      这个库下载时用'beautifulsoup4', 使用的时候用'bs4'
      
      注:使用bs4做数据解析时需要依赖'lxml'这个第三方库
      
      • 1
      • 2
      • 3
      • 4
    • 导入模块

      from bs4 import BeautifulSoup
      
      • 1
    • bs4的用法

      1)准备需要解析的数据(获取网页数据)
      2)基于网页源代码创建BeautifulSoup对象
      3)获取标签
      	soup.select(css选择器):获取css选择器选中的所有标签,返回值是一个列表,列表中的元素是标签对象。
      	soup.select_one(css选择器):获取css选择器选中的第一个标签,返回值是一个标签对象。
      	标签对象.select(css选择器):在指定标签中获取css选择器选中的所有标签,返回值是一个列表,列表中的元素是标签对象。
      	标签对象.select_one(css选择器):在指定标签中获取css选择器选中的第一个标签,返回值是一个标签对象。
      4)获取标签内容和标签属性
      a.获取标签内容:标签对象.text
      b.获取标签属性:标签对象.attr[属性名]
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      # 一个bs4使用的完整代码
      
      # 导入解析相关类
      from bs4 import BeautifulSoup
      
      # bs4的用法
      # 1)准备需要解析的数据(获取网页数据)
      html = open('files/test.html', encoding='utf-8').read()
      
      # 2)基于网页源代码创建BeautifulSoup对象:soup对象代表网页对应的html标签(整个网页)
      soup = BeautifulSoup(html, 'lxml')
      
      # 3)获取标签
      # soup.select(css选择器):获取css选择器选中的所有标签,返回值是一个列表,列表中的元素是标签对象。
      # soup.select_one(css选择器):获取css选择器选中的第一个标签,返回值是一个标签对象。
      result = soup.select('p')
      print(result)    # [

      你是大笨蛋

      ]
      result = soup.select_one('p') print(result) #

      你是大笨蛋

      # 标签对象.select(css选择器):在指定标签中获取css选择器选中的所有标签,返回值是一个列表,列表中的元素是标签对象。 # 标签对象.select_one(css选择器):在指定标签中获取css选择器选中的第一个标签,返回值是一个标签对象。 # 4)获取标签内容和标签属性 p = soup.select_one('p') img = soup.select_one('img') # a.获取标签内容:标签对象.text print(p.text) # 你是大笨蛋 # b.获取标签属性:标签对象.attr[属性名] print(img.attrs['src']) # 123
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31

    3.基于xpath的解析器(lxml

    三、保存数据:csv、Excel

    前面有文章讲了数据写入和读出。

    四、完整策略

    在这里插入图片描述

  • 相关阅读:
    python写好的程序打包成exe可执行文件
    算法题:分别用c++/python/java实现回文数
    LabVIEW和NIUSRP硬件加快了认知无线电开发
    深入探索Sharding JDBC:分库分表的利器
    JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
    mysql迁移后验证数据一致性
    对负采样(negative sampling)的一些理解
    Java String、StringBuffer和StringBuilder的相关总结
    C++的爬山算法
    Java线程池中的基础问题
  • 原文地址:https://blog.csdn.net/simple_daytime/article/details/126351271