Python3爬虫1

  1. 爬虫原理:请求网站并提取数据的自动化程序
    1. 通用爬虫:搜索引擎爬虫;聚焦爬虫:获取某一垂直领域的数据或者有明确的检索需求,需要过滤掉一些无用的信息
    2. HTTP协议:用于从WWW服务器传输文本到本地浏览器的传送协议;HTTPS协议是加密的超文本传输协议
      1. HTTP主要请求方式
        1. GET请求:是以实体的方式得到由请求URL所指定资源的信息
        2. POST请求:用来向目的服务发出请求,并且带上某些信息,如果用户输入的数据包敏感数据,那么使用POST为好
        3. PUT请求:请求服务器存储一个资源,通常要指定存储的位置
        4. DELETE请求:请求服务器删除一个资源
        5. HEAD请求:请求获取对应的HTTP头信息
        6. OPTIONS请求:可以获得当前URL所支持的请求类型
      2. HTTP头部信息:HTTP头部信息由众多的头域组成,每个头域由一个域名,冒号和域值三部分组成;F12->Network->Doc即主要请求,其中的Headers分页即请求头,包含请求头部信息
        1. Request Method代表的是请求方式,HTTP/1.1表示使用HTTP1.1协议标准,200OK说明请求成功
        2. Host头域,指定请求资源的Intenet主机和端口号,必须表示请求URL的原始服务器或网关的位置;即网址
        3. User_Agent头域,里面包含发出请求的用户信息,其最终由使用的浏览器型号,版本和操作系统的信息。这个头域经常用来作为反爬虫的措施,普通爬虫不包含User_Agent
        4. Accept:浏览器支持的内容类型
        5. Accept-Encoding:浏览器支持的语言类型
        6. Connection:客户端和服务器的连接类型,对应的字段值有keep-alive持久性连接和close单方面管理连接
        7. Referer来源网址地址
    3. 爬虫流程
      1. 网页特征
        1. 网页都有自己唯一的URL(统一资源定位符)来进行定位
        2. 网页都使用HTML (超文本标记语言)来描述页面信息
        3. 网页都使用HTTP/HTTPS(超文本传输协议)协议来传输HTML数据
      2. 基本流程
        1. 发起请求:通过HTTP库向目标站点发起请求,即发送一个Request,请求可以包含额外的headers等信息,等待服务器响应
        2. 获取响应内容:如果服务器能正常响应,会得到一个Response,Response的内容便是所要获取的页面内容,类型可能有HTML,Json字符串,二进制数据(如图片视频)等类型
        3. 解析内容:得到的内容可能是:
          1. HTML,可以用正则表达式、网页解析库进行解析
          2. Json,可以直接转为Json对象解析
          3. 二进制数据,可以做保存或者进一步的处理
        4. 保存数据:保存形式多样,可以存为文本,也可以保存至数据库,或者保存特定格式的文件
  2. 爬虫与反爬虫
    1. 反爬虫机制:
      1. 分析用户请求的Headers信息,网站中应用的最多
      2. 验证用户行为,在短时间内是否频繁访问网站
      3. 动态页面增加爬虫难度
    2. 应对策略
      1. 构造用户请求的Headers信息
      2. 使用代理服务器并经常切换代理服务器
      3. 利用工具软件,例如selenium+phantomJs
  3. 请求与响应
    1. 请求Request:浏览器发送消息给该网址所在的服务器
      1. 主要方式有GET和POST
      2. URL统一资源定位符
      3. 请求头部信息包括User-Agent,Host,Cookies
      4. 请求时能携带额外的数据,即POST
    2. 响应Response:服务器收到浏览器发送的消息后,能够根据浏览器发送消息的内容,做相应处理,然后把消息回传给浏览器
      1. 响应状态:200成功,301跳转,403forbidden禁止访问,404找不到页面,502服务器错误
      2. 响应头,如内容类型,内容长度,服务器信息,设置Cookie(用户行为)等
      3. 响应体包含最主要的请求资源的内容
    3. 浏览器收到服务器的Response信息后,会对信息进行相应处理,然后展示
  4. 数据选择和处理
    1. 抓取数据类型:
      1. 网页文本HTML文档,Json格式文本
      2. 图片的二进制文件
      3. 视频的二进制文件及其他
    2. 解析方式
      1. 直接处理
      2. Json解析
      3. 正则表达式
      4. BeautifulSoup
      5. PyQuery
      6. XPath
    3. JavaScript渲染问题
      1. 分析Ajax
      2. Selenium/WebDriver
      3. Splash
      4. PyV8/Ghost.py
    4. 保存数据
      1. 文本
      2. 关系型mysql和非关系型Redis数据库
      3. 二进制文件,如图片,视频
  5. *爬虫工具gooseeker,八爪鱼等
  1. 爬虫基本请求库Urllib:Urllib是python内置的HTTP请求库,也是python爬虫的基础库
    1. *Urllib.request请求模块,Urllib.Error异常处理模块,Urllib.parse解析
    2. response=urllib.request.urlopen(url,data,timeout)->response.read().decode('')
      1. 前端知识:<head>包含的<meta>内有content="charset="即网页编码属性
      2. url网址
      3. data访问网站时发送的数据包,默认null
      4. timeout等待时长
      5. decode('')解码,把字节流形式数据以网页的字符格式转化为字符串
    3. urllib.request.urlretrieve(url,filename='*.html')直接存储html文档
      1. **每次操作都会有缓存,多次爬虫必须加上清除缓存的步骤urllib.request.urlcleanup()
    4. 搜索引擎框中的中文会自动转化为ASCII码进行搜索,所以在构造搜索网页url时,urllib.request.quote(keyword)将搜索关键字先转化为编码
    5. POST数据传送
      1. urllib.parse.urlencode({}).encode('utf-8')HTML中post方法表单中的输入框的标签name对应想要上传值的字典;用encode()将字符串转化为相应编码格式的二进制字节流形式->urllib.request.urlopen(url,data)中的data即urllib.parse.urlencode({}).encode('utf-8')想要上传的字节流数据
      2. encode编码,decode解码
    6. **urllib高级用法:应对反爬虫设置
      1. 设置Headers
        1. urllib.request.urlopen(urllib.request.Request(url=url,headers={'User-Agent':''})).read().decode();urllib.request.Request()即设置请求细节,放入headers的User-Agent浏览器信息
      2. Proxy(代理)的设置
        1. urllib.request.install_opener(urllib.request.build_opener(urllib.request.ProxyHandler({'http':proxy_addr})))设置全局代理服务器,传入proxy_addr需要加上端口
      3. Timeout设置urllib.request.urlopen(url,data,timeout),设置一次请求的等待时间,超过即停止请求
      4. 设置Cookie:Cookie即储存在浏览器中的用户信息,可用于绕过登录等,http是无状态的协议,不保存登录信息
        1. import http.cookiejar
        2. 利用登录跳转页面url
        3. 写data登录信息:urllib.parse.urlencode({}).encode('utf-8')
        4. cjar=http.cookiejar.CookieJar()创建对象
        5. 创建cookie处理器和opener对象,并加载cookie设置urllib.request.install_opener(urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cjar)))
        6. urllib.request.urlopen(url,data)请求得到登录后的页面
      5. 异常处理
        1. import urllib.error
        2. try:...except urllib.error.URLError|HTTPError as e:...;捕捉到URLError|HTTPError错误
  2. 爬虫高级请求库Request:import requests
    1. 特点
      1. Requests是用python语言基于urllib编写的HTTP请求库
      2. Requests实现HTTP请求非常简单,更具有Python风格,操作更加人性化
      3. Requests库是第三方模块,需要额外进行安装pip install requests
    2. 功能
      1. GET和POST
        1. requests.get(url,headers={'User-Agent':''},cookies={},proxies={},timeout=):get请求
        2. requests.post(url,data={}):post请求,data传入数据为method="post"的表单中的输入框的name和对应输入值
        3. requests.get(url).content|text:请求的字节流|文本输出,content.decode可解码
      2. 响应与编码:import chardet检测字符串和文件编码
        1. requests.get(url).encoding=chardet.detect(requests.get(url).content)['encoding']获取当前get请求网页的编码格式,直接赋值给get请求网页文件的编码
        2. *requests.get(url).status_code获取当前get请求网页的响应值
      3. Headers设置
        1. requests.get(url,headers):利用headers的User-Agent浏览器信息
      4. Cookies设置
        1. 登录后界面的headers内的cookie信息
        2. 传入的cookies为字典,且先用for循环将cookie按;切分,以第一个等号分隔name和value
          1. for i in string.split(';'):name,value=i.strip().split('=',1) cookie[name]=value
        3. requests.get(url,cookies=)利用cookies
      5. 代理设置
        1. 上网查找代理ip->proxies={'http':'ip:port'}
        2. requests.get(url,proxies={})利用ip
      6. 超时设置
        1. requests.get(url,timeout=)设置请求时间;可用r.status_code查看页面请求状态
  3. 爬虫解析法Beautiful Soup:是一个可以从HTML或XML文件中查找提取数据的Python库,它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式;效率较高上手简单;pip install bs4;解析器:pip install lxml
    1. *解析器BeautifulSoup(markup,"")
      1. python标准库:html.parser,python内置
      2. lxml HTML解析器:lxml
      3. lxml XML解析器:xml,唯一支持XML的解析器
      4. html5lib:html5lib,以浏览器的方式解析文档,生成HTML5格式的文档
    2. BS将HTML文档转换成一个树形结构,每个节点即python对象,对象可分为4类
      1. Tag:标签<div>,<p>
      2. NavigableString:字符内容操作对象,表示标签里面的内容
      3. BeautifulSoup:文档对象,表示的是一个文档的全部内容
      4. Comment:特殊类型的NavigableString,为标签内注释的内容
    3. 使用
      1. from bs4 import BeautifulSoup
      2. 创建BS对象:读取HTML文档或使用HTML格式字符串soup=BeautifulSoup(html,"解析器")
      3. 利用BS对象:
        1. *soup.prettify()标准缩进HTML文档输出
        2. 获取标签:soup.标签名;若有多个同名标签,只能获取第一个标签
        3. 获取属性:soup.标签名.attrs,获取属性字典;soup.标签名['属性名']
        4. 获取标签中间的内容:soup.标签名.string
          1. 如果标签中只有一个子标签,返回子标签中文本内容
          2. 如果标签中有多个子标签,返回None
        5. 遍历文档树
          1. 子节点
            1. soup.标签.contents:匹配标签的所有子节点及其内容
            2. soup.标签.children:匹配标签的子节点列表迭代器,for i in soup.p.children
          2. 父节点
            1. soup.标签.parent:匹配标签的父节点及其内容
            2. soup.标签.parents:匹配标签的父节点列表迭代器
          3. 兄弟节点
            1. soup.标签.next|previous_sibling:匹配标签的同级前|后节点;实测不输出
            2. soup.标签.next|previous_siblings匹配标签的同级前|后所有节点列表迭代器;最好用这个输出兄弟节点
        6. 搜索文档树:
          1. soup.find_all(''):根据标签名,属性,内容查找文档;返回列表
            1. soup.find_all([])多个标签
            2. soup.find_all(re.compile('d+'))正则表达式查找,整个标签中包含d字符
            3. soup.find_all(id='')关键字参数查找
            4. soup.find_all(text='')标签中间内容匹配,得到的也是标签的中间内容
            5. for i in soup.find_all('p'):print(i.find_all('a'))嵌套查找,soup.find_all()也是BS对象
          2. soup.find(''):返回的匹配结果的第一个元素
          3. soup.find_parents()|soup.find_parent():查找所有|一个父节点
          4. soup.find_next|previous_sibling(s)():查找后|前所有|一个兄弟节点
          5. soup.find_(all_)next|previous():查找后|前所有|一个节点
        7. css选择器:返回list;css文件即对网页各个元素进行样式设计,对网页元素的多种选择方法都能在.select('')内使用
          1. css语法:
            1. 标签名不加修饰
            2. 类名前加.,id名前加#
            3. a,p:找到所有的a和p标签
            4. a p:找到a标签下所有的p标签
            5. soup.select().get_text():获取标签中间的文本内容
          2. 操作
            1. soup.select('#id'):id查找
            2. soup.select('.class'):class查找
            3. soup.select("a[href='']"):css写法的查询
  4. 爬虫解析法Xpath:Xpath原本是在可扩展标记语言XML中进行数据查询的一种描述语言;对于标记语言都有非常友好的支持,如超文本标记语言HTML
    1. 选取节点
      1. nodename:选取节点的所有子节点
      2. /:起始为/则表示从根节点选取(且为元素的绝对路径);bookstores/book表示bookstores元素的后代的所有book元素
      3. //:从匹配选择的当前节点中选择文档中的节点,不考虑其位置
      4. .:选择当前节点
      5. ..:选择当前节点的父节点
      6. @:选择属性
      7. 谓语:查找某个特定的节点或者包含某个指定的值的节点,谓语被嵌在方括号中,类似索引
        1. /bookstores/book[1]:选取属于bookstores子元素的第一个book元素
        2. /bookstores/book[last()]:选取属于bookstores子元素的最后一个book元素
        3. /bookstores/book[position()<3]:选取属于bookstores子元素的前两个book元素
        4. //title[@lang]:选取所有拥有名为lang的属性的title元素
        5. /bookstores/book[price>35]:选取bookstores元素中的所有book元素,且其中的price元素>35
        6. /bookstores/book[price>35]/title:选取bookstores元素中的所有book元素,且其中的price元素>35,下面的title元素
      8. 选取未知节点
        1. *:匹配任何元素节点
        2. @*:匹配任何属性节点
        3. node():匹配任何类型节点
      9. 路径选取
        1. /bookstores/*:选取bookstores元素的所有子元素
        2. //*:选取文档中的所有元素
        3. //title[@*]:选取所有带有任何属性的title元素
        4. //book/title|//book/price:选取book元素的所有title和price元素
        5. //book|//price:选取文档中所有的title和price元素
        6. /bookstores/book/title|//price:选取属于bookstores元素的book元素的所有title元素和文档中所有的price元素
        7. *div是除法
    2. 操作
      1. from lxml import etree
      2. 初始化构造Xpath解析对象:html=etree.HTML(text),text即HTML文档
      3. 利用Xpath对象
        1. html.xpath('//p'):查询所有p标签
        2. html.xpath('//@name'):查询所有name属性的值
        3. html.xpath('//*[@name]'):查询所有包含name 属性的标签
        4. html.xpath('//*[@name="desc"]'):)查询所有包含name属性,并且name属性值为desc的标签
        5. for p in html.xpath('//p'):print(p.text):查询所有p标签中间的文本内容,不包含子标签
        6. for p2 in html.xpath('//p'):print(p2.xpath('string(.)')):查询多个p标签下的所有文本内容,包含子标签中的文本内容
        7. html.xpath('//div/p[3]/@name'):第三个p标签的name属性值
  5. 爬虫解析法正则表达式:上手难但最全面;用规则字符串来表达对字符串的一种过滤逻辑;
    1. 操作
      1. import re
      2. re.search(pattern,string):pattern为正则表达式'',string是被检验的字符串'';匹配到的字符和所占位置,从0开始,左闭右开
      3. re.findall(pattern,string):返回所有匹配正则表达式的字符串列表
      4. re.compile(string):返回pattern对象
      5. re.match(pattern,string):从string的第一个字符开始匹配,如果出错直接返回None
      6. re.sub(pattern,replace,string,count):string中所有匹配的字符串转化为replace,count可以指定次数
    2. 原子:
      1. 普通字符:'yue'
      2. 非打印字符:'\n'换行符等
      3. 通用字符:
        1. \w:匹配字母、数字、下划线;等价于'[A-Za-z0-9_]'
        2. \W:匹配非字母、数字、下划线;等价于 '[^A-Za-z0-9_]'
        3. \s:匹配任何空白字符,包括空格、制表符、换页符
        4. \S:匹配任何非空白字符
        5. \d:匹配一个数字字符
        6. \D:匹配一个非数字字符
        7. \A:匹配字符串开始
        8. \Z:匹配字符串结束,如果存在换行,只匹配到换行前的结束字符
        9. \z:匹配字符串结束
        10. \G:匹配最后匹配完成的位置
        11. \n:匹配换行符
        12. \t:匹配制表符
      4. 元字符:
        1. ^:匹配字符串开头
        2. $:匹配字符串结尾
        3. .:匹配除换行符(\n、\r)之外的任何单个字符,当re.DOTALL标记被指定时,可以匹配任意字符;\.匹配点自身
        4. []:原子集
        5. [^]:非原子集,不存在原子集中的字符
        6. *:匹配0或多个的前一个原子,元字符或原子集;贪婪模式,提取后面符合规则的所有字符
        7. +:匹配1或多个的前一个原子,元字符或原子集;贪婪模式
        8. ?:匹配0或1个的前一个原子,元字符或原子集,.*?这里的?指的是.*;非贪婪模式
        9. |:模式选择符,设置多个模式,匹配时,可以从中任意一个模式匹配,类似原子集
        10. ():模式单元符,将原子组合成一个大原子使用,用findall则只截取pattern的()内的字符串
        11. {n}:精确匹配n个前面表达式
        12. {n,m}:匹配n到m次由前面正则表达式定义的片段,贪婪模式
      5. 原子表(字符集):[p\wh],定义一组地位平等的原子,然后匹配的时候会取该原子集中任意一个原子进行匹配
    3. 实例:
      1. 匹配.com和.cn后缀的网址:[a-zA-Z]+://[^\s]*[.com|.cn]
      2. 匹配电话号码:\d{4}-\d{7}|\d{3}-\d{8}
      3. 匹配电子邮箱:
        1. <br><a href='(.*?)'>
        2. [a-zA-Z+-]+@[a-zA-Z-]+\.\w+([.-]\w+)*,邮箱通用

猜你喜欢

转载自blog.csdn.net/u013103305/article/details/84529972