Python爬虫

爬虫简介

  • 爬虫定义:是一种按照一定规则,自动地抓取万维网信息的程序或脚本
  • 两大特征:
    • 能按作者要求下载数据
    • 能自动在网络上流窜
  • 三大步骤:
    1. 下载网页
    2. 提取正确的信息
    3. 根据一定规则自动跑到另外一个网页上并循环前两步内容
  • 爬虫分类:
    • 通用爬虫
    • 专用爬虫(聚焦爬虫)
  • Python网络包
    • Python3.x:urllib, urllib3, httplib2, requests

urllib

  • 包含模块:

    • urllib.request:打开和读取urls
    • urllib.error:包含urllib.request产生的常见错误,使用try捕捉
    • urllib.parse:包含即系url的方法
    • urllib.robotparse:解析robots.txt文件
  • 网页编码问题解决

    • charset:可以自动检测页面文件的编码格式,但可能有误
    • 需要安装,命令:conda install charset
  • urlopen的返回对象

    • geturl:返回请求对象的url
    • info:请求反馈对象的meta信息
    • getcode:返回http的code
  • request.data的使用

    • 访问网络的两种方法
      • get
        • 利用参数给服务器传递信息
        • 参数为dict,然后用parse编码
      • post
        • 一般向服务器传递参数使用
        • post是把信息自动加密处理
        • 我们如果想使用post信息,需要用到data参数
        • 使用post,意味着http的请求头可能需要更改:
          • Content-Type: application/x-www.form-urlencode
          • Content-Length: 数据长度
          • 简而言之,一旦更改请求方法,请注意其他请求头部信息要与之相适应
        • urllib.parse.urlencode可以将字符串自动转换成上面的格式
        • 为了更好地设置请求信息,单纯的通过urlopen函数已经不太好用了,此时需要利用request.Request类
  • urllib.error

    • URLError产生的原因:
      • 没网
      • 服务器链接失效
      • 找不到指定服务器
      • 是OSError的子类
    • HTTPError是URLError的一个子类
    • 两者区别:
      • HTTPError是对应HTTP请求的返回码错误,如果返回错误码是400以上的,则引发HTTPError
      • URLError对应的一般是网络出现问题,包括url问题
      • 关系区别:OSError->URLError->HTTPError
  • UserAgent

    • UserAgent:用户代理,简称UA,属于heads的一部分,服务器通过UA来判断访问者身份
    • 常见的UA值,使用的时候可以直接复制粘贴,也可以用浏览器访问的时候抓包
    • 设置UA可以通过两种方式
      • headers
      • add_header方法
  • ProxyHandler处理(代理服务器)

    • 使用代理IP,是爬虫的常用手段
    • 代理用来隐藏真实访问中,代理也不允许频繁访问某一个固定网站
    • 使用步骤:
      1. 设置代理地址
      2. 创建ProxyHandler
      3. 创建Opener
      4. 安装Opener
  • cookie & session

    • 由于http协议的无记忆性,人们为了弥补这个缺憾,所采用的一个补充协议

    • cookie是发放给用户(即http浏览器)的一段信息,session是保存在服务器上的对应的另一半信息,用来记录用户信息

    • cookie 和 session的区别

      • 存放位置不同
      • cookie不安全(即应该存放不敏感的信息)
      • session会保存在服务器上一定时间,会过期
      • 单个cookie保存数据不超过4k,很多浏览器限制一个站点最多保存20个
    • session的存放位置

      • 存在于服务器端
      • 一般情况,session是放在内存中或者数据库中
    • 使用cookie登录

      • 直接把cookie复制下来,然后手动放入请求头
      • http模块包含一些关于cookie的模块,通过他们可以自动使用cookie
        • CookieJar
          • 管理存储cookie,向传出的http请求添加cookie
          • cookie存储在内存中,CookieJar实例回收后cookie将消失
        • FileCookieJar
          • 使用文件管理cookie
          • filename是保存cookie的文件
        • MozillaCookieJar
          • 创建与Mocilla浏览器cookie.txt兼容的FileCookieJar实例
        • LwpCookieJar
          • 创建与libwww-perl标准兼容的Set-Cookie3格式的FileCookieJar实例
        • 关系:CookieJar->FileCookieJar->MozillaCookieJar & LwpCookieJar
    • 处理复杂的请求

          # 生成cookie管理器
          cookie_handler = request.HTTPCookieProcessor(cookie)
          # 创建http请求管理器
          http_handler = request.HTTPSHandler()
          # 生成https管理器
          https_handler = request.HTTPSHandler()
      
      • 建立handler后,使用opener打开,打开后相应的业务由相应的handler处理
      • cookie的属性
        • name:名称
        • value:值
        • domain:可以访问此cookie的域名
        • path:可以访问此cookie的路径
        • expires:过期时间
        • size:大小
        • http字段
    • cookie的保存-FileCookieJar

    • cookie的读取

  • SSL

    • SSL证书就是指遵守SSL安全套阶层协议的服务器数字证书(SercureSocketLayer)
    • 美国网景公司开发
    • CA(CertifacateAuthority)是数字证书认证中心,是发放、管理、废除数字证书的收信人的第三方机构
    • 遇到不信任的SSL证书,需要单独处理
  • JS加密

    • 有的反爬虫策略采用js对需要传输的数据进行加密处理(通常是MD5加密)
    • 经过加密,传输的就是密文,但是加密函数或者过程一定是在浏览器中完成的,依旧是一定会js代码暴露给使用者
    • 通过阅读加密算法,就可以模拟出加密过程,从而达到破解的效果
  • AJAX

    • 异步请求
    • 一定会有url,请求方法,可能有数据
    • 一般使用json格式
  • Requests

    • HTTP for Humans,更简洁更友好

    • 继承了urllib的所有特征

    • 底层使用了urllib3

    • 开源地址:https://github.com/kennethreitz/requests

    • 中文文档:http://docs.python-requests.org/zh_CN/latest/index.html

    • 安装命令:conda install requests

    • get请求

      • requests.get(url)
      • requests.request(“get”, url)
      • 可以带有headers和parmas参数
    • get返回内容

    • post

      • rsp = requests.post(url, data=data)
      • data,headers要求是dict类型
    • proxy

      • proxies = {
        “http”: “address of proxy”
        “https”: “address of proxy”
        }

      rsp = requests.request(“get”, “http://xxx”, “proxies=proxies”)

    • 用户验证

      • 代理验证
        • 可能需要用到HTTP basic Auth
        • 格式:用户名:密码@代理地址:端口地址
        • 例子:
        proxy = {"http":"test1:123456@192.138.1.123:4444"}
        
        rsp = requests.get("http://xxx", prixies=proxy)
        
    • web客户端验证

      • 如果遇到web客户端验证,需要添加auth=(用户名,密码)

      • 例子:

      auth = ("test1", "123456")
      rsp = requests.get("http://www.baidu.com", auth=auth)
      
    • cookie

      • requests可以自动处理cookie信息
      • 例子:
      rsp = requests.get("http://xxx")
      # 如果地方发武器传送过来cookie信息,则可以通过反馈的cookie属性得到
      # 返回一个cookiejar实例
      cookiejar = rsp.cookies
      
      # 可以将cookiejar转换为字典
      cookiedict = request.utils.dict_from_cookiejar(cookiejar)
      
    • session

      • 模拟一次对话,从客户端连接服务器开始,到客户端浏览器断开
      • 能让我们跨请求时保持某些参数,比如在同一个session实例发出的,所有请求之间保持一个cookie
      • 例子:
      # 创建session对象,可以保持cookie值
      ss = requests.session()
      headers = {'User-Agent': 'xxx'}
      data = {'name': 'xxx'}
      
      # 由创建的session管理请求
      ss.post('http://xxx', data=data, headers=heade rs)
      
      rsp = ss.get('xxxx')
      
    • https请求验证ssl证书

      • 参数verify表示是否需要验证ss证书,默认时True
      • 如果不需要验证ssl证书,则设置成False
      • 例子
      rsp = requests.get("https://www.baidu.com", verify=False)
      # 如果用verify=True访问没有ssl证书的网站会报错
      

页面解析和数据提取

  • 结构数据:先由结构,再谈数据
    • JSON文件
      • JSON Path
      • 转换成Python类型进行操作(JSON类)
    • XML文件
      • 转换成Python类型(xmltodict)
      • XPath
      • CSS选择器
      • 正则
  • 非结构数据:先有数据,再谈结构
    • 文本、电话号码、邮箱地址…
    • 通常处理此类数据,使用正则表达式
    • Html文件
      • 正则
      • XPath
      • CSS选择器

正则表达式

  • 一套规则,可以在字符串文本中进行搜查替换等

  • 正则使用方法:

    • match:从开始位置查找,一次匹配
    • search:从任何位置查找,一次匹配
    • findall:全部匹配,返回列表
    • finditer:全部匹配,返回迭代器
    • split:分割字符串,返回列表
    • sub:替换
  • 匹配中文

    • 中文unicode范围主要在[u4e00-u9fa5]
  • 贪婪与非贪婪

    • 贪婪模式:在整个表达式匹配成功的前提下,尽可能多的匹配
    • 非贪婪模式:在整个表达式匹配成功的前提下,尽可能少的匹配
    • Python里面数量词默认是贪婪模式
    • 例如:
      • 查找文本abbbbbbccc
      • re是ab*
      • 贪婪模式:结果是abbbbbb
      • 非贪婪模式:结果是a
  • XML(EXtensibleMarkupLanguage)

    • 概念:父节点,子节点,先辈节点,兄弟节点,后代节点
  • XPath(XML Path Language)

    • 是一门在XML文档中查找信息的语言

    • 官方文档:http://www.w3school.com.cn/xpath/index.asp

    • XPath开发工具

      • 开源的XPath表达式工具:XMLQuite
      • Chrome插件:Xpath Helper
      • Firefix插件:Xpath Checker
    • 常用路径表达式

      • nodename:选取此节点下的所有子节点
      • /:从根节点开始选
      • //:选取元素,而不考虑元素的具体位置
      • .:当前节点
      • …:父节点
      • @:选取属性
      • 案例
        • booksotre:选取booksotre下的所有子节点
        • /booksotre:选取根元素
        • booksotre/book:选取booksotre下所有名字为book节点的子元素
        • //book:选取book子元素
        • //@lang:选取名称为lang的所有属性
    • 谓语(Predicates)

      • 谓语用来查找某个特定的节点,被镶嵌在方括号中
      • /booksotre/book[1]:选取属于booksotre下叫book的第一个元素
      • /booksotre/book[last()]:选取属于booksotre下叫book最后一个的元素
      • /booksotre/book[last()-1]:选取属于booksotre下叫book倒数第二个的元素
      • /booksotre/book[position()<3]:选取属于booksotre下叫book的前两个元素
      • /booksotre/book[@lang]:选取属于booksotre下叫book且含有属性lang的元素
      • /booksotre/book[@lang="cn"]:选取属于booksotre下叫book且含有属性lang的值是cn的元素
      • /booksotre/book[@price<90]:选取属于booksotre下叫book且属性price的值小于90的元素
      • /booksotre/book[@price<90]/title
        :选取属于booksotre下叫book且属性price的值小于90的元素的子元素title
    • 通配符

      • *:任何元素节点
      • @*:匹配任何属性节点
      • node():匹配任何类型的节点
    • 选取多个路径

      • //book/title | //book/author:选取book元素中的title和author元素
      • //title | //price:选取文档中所有的title和price元素

lxml库

  • 局部遍历,速度较快
  • python的HTML/XML解析器
  • 官方文档:https://lxml.de/xpathxslt.html
  • 功能
    • 解析HTML
    • 读取文件
    • etree和XPath配合使用

BeautifulSoup4

  • 全局遍历,速度较慢
  • 官方文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc/#
  • 四大对象
    • Tag

      • 对应HTML中的标签
      • 可以通过soup.tag_name来定位标签
      • Tag两个重要属性
        • name:名称
        • sttrs:属性
    • NavigableString

      • 对应内容值
      • string:内容值
    • BeautifulSoup

      • 表示的是一个文档的内容,大部分可以把它当作tag对象
      • 一般我们可以用soup来表示
    • Comment

      • 特殊类型的NavagableString对象
      • 对其输出,则内容不包括注释符号
    • 遍历文档对象

      • contents:tag的子节点以列表的方式给出
      • children:子节点以迭代器形式返回
      • descendants:所有孙子节点
    • 搜索文档对象

      • find_all(name, attrs, recursive, text, **kwargs)
        • name:按照输入的字符串搜索,可以传入的内容有
          • 字符串
          • 正则表达式
          • 列表
        • attrs:用来表示属性
        • text:对应tag的文本值
    • CSS选择器

      • 使用soup.select,返回一个列表
      • 通过标签名称:soup.select("title")
      • 通过类名:soup.select(".content")
      • 通过ID:soup.select("#name_id")
      • 组合查找:soup.select("div #input_content")
      • 属性查找:soup.select("img[class='photo']")
      • 获取tag内容:tag.get_text
    • 几个常用提取信息工具的比较

      • 正则:很快,不好用,无需安装
      • beautifulSoup:慢,使用简单,安装简单
      • lxml:比较快,使用简单,安装一般

正则表达式

  • 一套规则,可以在字符文本中进行搜查替换等

动态HTML

动态HTML介绍

  • JavaScript
  • jQuery
  • Ajax
  • DHTML
  • Python采集动态数据
    • 从JavaScript代码入手采集
    • Python第三方库运行JavaScript,直接采集你在浏览器看到的内容

Selenium

  • Selenium:Web自动化测试工具

    • 自动加载页面
    • 获取数据
    • 截屏
    • 安装:pip install selenium
    • 官网:https://www.seleniumhq.org/
  • Selenium库有一个WebDriver的API

  • WebDriver可以跟页面上的元素进行各种交互,用它可以来进行爬取

chrome + chromedriver

  • chromedriver:是一个无界面的浏览器
    • 好处:相比有界面的浏览器,它不需要渲染,所以爬取数据的效率更高
  • Selenium操作主要分两大类
    • 得到UI元素
      • find_element_by_id
      • find_elements_by_name
      • find_elements_by_xpath
      • find_elements_by_link_text
      • find_elements_by_partial_link_text
      • find_elements_by_tag_name
      • find_elements_by_class_name
      • find_elements_by_css_selector
    • 基于UI元素操作的模拟
      • 单击
      • 右键
      • 拖拽
      • 输入
      • 可以通过导入ActionsChains类来做到

验证码问题

  • 验证码:识别机器人或者爬虫

  • 分类:

    • 简单图片
    • 极验:www.geetest.com
    • 组合图片
    • 电话
    • google验证
  • 验证码破解:

    • 通用方法:
      • 下载网页和验证码
      • 手动输入验证号码
    • 简单图片
      • 使用图像识别软件或者文字识别软件
      • 可以使用第三方图像验证码破解网站:www.chaojiying.com
    • 极验:www.geetest.com
      • 破解比较麻烦
      • 可以模拟鼠标等移动
      • 一直在进化
    • 组合图片
      • 放弃
    • 电话
      • 语音识别
    • google验证

Tesseract

  • 机器视觉领域的基础软件
  • 但识别率不高
  • OCR:OpticalChracterRecognition,光学文字识别
  • Tessert:一个OCR库,有google赞助
  • 安装:
    • Windows:下载文件,放到Python目录下,设置环境变量
    • Linux:apt-get install tesseract-ocr
  • 安装完后还需要pytesseract
    • pip install pytesseract

Scrapy爬虫框架

  • 爬虫框架

    • Scrapy
    • pyspider
    • crawley
  • Scrapy框架介绍

    • https://scrapy-chs.readthedocs.io/zh_CN/latest/index.html
    • https://scrapy.org/
  • 安装

    • pip install scrapy
  • 概述

    • 包含各个部件
      • ScrapyEngine:神经中枢,大脑,核心
      • Scheduler调度器:引擎发来的request请求,调度器需要处理,然后交换引擎
      • Downloader下载器:对引擎发来的requests发出请求,得到response给Spider处理
      • Spider爬虫:负责把下载器得到的网页/结果进行分解,分解成数据+链接,数据交给ItemPipeline,链接交交给Scheduler
      • ItemPipeline管道,详细处理Item
      • DownloaderMiddleware下载中间件:自定义下载的功能扩展组件
  • 爬虫程序大概流程

    • 新建项目:scrapy startproject xxx
    • 明确需要目标/产出:编写item.py
    • 制作爬虫:地址spider/xxspider.py
    • 存储内容:pipelines.py
  • ItemPipeline

    • 对应的是pipelines文件
    • 爬虫提取出数据存入item后,item中保存的数据需要进一步处理,比如清洗,去重,存储等
    • pipeline需要处理process_item函数
      • process_item:
        • spider提取出来的item作为参数传入,同时传入的还有spider
        • 必须返回一个Item对象,被丢弃的item不会被之后的pipeline处理
      • init:构造函数
        • 进行一些必要的参数初始化
      • open_spider(spider)
        • spider对象被开启的时候调用
      • close_spider(spider)
        • 当spider对象被关闭的时候调用
  • Spider

    • 对应的是文件夹spiders下的文件
    • init:初始化爬虫名称,start_urls列表
    • start_requests:生成Requests对象交给Scrapy下载并返回response
    • parse:根据返回的response解析出相应的item,item自动进入pipeline;如果需要,解析出url,url自动交给requests模块,一直循环下去
    • start_request:此方法仅能被调用一次,读取start_urls内容并启动循环过程
    • name:设置爬虫名称
    • start_urls:设置开始第一批爬取的url
    • allow_domains:spider允许爬取的域名列表
    • start_request(self):只被调用一次
    • parse
    • log:日志记录
  • 中间件(DownloaderMiddlewares)

    • 中间件是处于引擎和下载器中间的一层组件
    • 可以有很多个,按顺序加载执行
    • 作用:对发出的请求和返回的结果进行预处理
    • 在Middlewares文件中
    • 需要在settings中设置以便生效
    • 一般一个中间件完成一项功能
    • 必须实现以下一个或多个方法
      • process_request(self, request, spider)
        • 在request通过时被调用
        • 必须返回None或Response或Request或raise IgnoreRequest
          • None:scrapy将继续处理该request
          • Request:scrapy会停止调用process_request并冲洗调度返回的request
          • Response:scrapy将不会调用其他的process_request或者process_exception,直接将该response作为结果同时调用process_response函数
      • process_response(self, request, response, spider)
        • 跟process_request大同小异
        • 每次返回结果的时候会自动调用
        • 可以有多个,按顺序调用
  • 去重

    • 为了防止爬虫陷入死循环,需要去重
    • 即在spider中的parse函数中,返回Request的时候加上dont_filter=False参数
  • 如何在scrapy使用selenium

    • 可以放入中间件的process_request函数中
    • 在函数中调用selenium,完成爬取后返回Response

scrapy-shell

  • 启动
    • Linux:ctrl+T,打开终端,输入scrapy shell “url:xxx”
    • windows:打开Anaconda Prompt,输入scrapy shell “http://xxx”
    • 启动后自动下载指定url的网页
    • 下载完成后,url的内容保存在response变量中,如果需要,可以调用response
  • response
    • 爬取到的内容保存在response中
    • response.body时网页的代码
    • response.headers是返回的http的头信息
    • response.xpath()允许使用xpath语法选择内容
    • response.css()允许使用css语法选取内容
  • selector
    • 选择器,允许用户使用选择器来选择自己想要的内容
    • response.selector.xpath:response.xpath是selector.xpath的快捷方式
    • response.selector.css:response.css是它的快捷方式
    • selector.extract:把节点的内容用unicode形式返回
    • selector.re:允许用户通过正则选取内容

分布式爬虫

  • 单机爬虫的问题
    • 单机效率
    • IO吞吐量
  • 多爬虫问题
    • 数据共享
    • 在空间上不同的的多台机器,可以成为分布式
  • 解决方法
    • 共享队列
    • 去重
  • 共享队列-Redis
    • 内存数据库
    • 同时可以落地保存到硬盘
    • 可以去重
    • 可以对保存的内容进行生命周期控制
    • 可以把它理解成一个dict, set, list的集合体
  • 内容保存数据库
    • MongoDB
    • MySQL等传统关系数据库
  • 安装scrapy_redis
    • pip install scrapy_reids
    • github.com/rolando/scrapy-redis
    • https://scrapy-redis.readthedocs.io/en/stable
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值