爬虫-静态网页爬取

爬虫

爬虫也叫网络蜘蛛,网络机器人.是一个自动下载网页的计算机程序或自动化脚本.网络爬虫像蜘蛛一样
在网络上爬行.它以一个称为种子集的URl集合为起点,沿着URl的丝线爬行.下载每一个URL所指向的网页,
分析网页,提前新URl,记录已经爬过的内容,循环往复,直到URL队列空或者满足条件.达到遍历URL的目的

python爬虫技术

爬虫原理

分为四种: 通用 聚焦 增量式 深沉

通用

由一批种子 爬取整个网络 采用深度优先 广度优先

聚焦

又叫主题网络爬虫
只选择性[爬取与预设主题相关的页面
四种:
    基于内容评价
        --将用户输入作为主题 爬取含有查询词的页面 但不知道有无关系
    基于链接结构
        --PageRank 爬取重要的页面
    基于增强学习
        --将增强学习引入爬虫 利用贝叶斯分类器对网页进行分类 计算重要性 进行排序
    基于语境图
        --构建语境图来学习网页间相关度 计算当前页面到相关页面的距离,距离近的优先

增量

只对已经下载的进行增量式更新,或只爬取新产生或者发生变化的网页
可以保证爬取页面的新
三种:
    统一更新法
        --相同频率访问所有的网页
    个体更新法,,,,
        --根据个体网页的改变频率决定访问频率
    分类更新法
        --将网页分为快网页 慢网页 分别设置不同的频率

深层

web页面分为深层和浅层 
浅层可以搜索到 
深沉不可以搜索到 隐藏在表单后 如登录后才能进入的网页

爬虫合法性

明确注意
    1. 个人隐私数据不可爬
    2. 明确禁止的数据不可爬 如密码等
    3. 注意版权问题 作者授权过的 不可以爬取后用于商业用途


robot.txt协议
    爬虫爬取数据 需要遵守网站拥有者针对爬虫制定的协议 robot.txt

认识反爬虫

网站所有者 把所有的网站访问者中识别爬虫并进行响应处理 (通常为禁用IP)的过程 叫做反爬虫
爬虫会消耗大量的服务器资源 增加运行压力

通过User-Agent校验反爬

浏览器发送请求时 会附带一部分的浏览器及当前系统环境的参数给服务器,
这部分被放在HTTP请求得Hearders部分

服务器会通过 User-Agent值来区别不同的浏览器

通过访问频度反爬

普通用户通过浏览器访问网页比爬虫慢得多 所以网站会对访问频率设置阈值来进行反爬

通过验证码反爬

有部分网站 必须要输入验证码才能继续操作

通过变换网页结构反爬

更换网页结构,使爬虫无法解析网页结构

通过账号权限反爬

有部分网站需要登录才可以继续操作

如何针对反爬虫

发送模拟User-Agent

发送模拟User-Agent来通过服务器的检验

调整访问频率

通过调整访问频率来确保不会被限制

通过验证码校验

可以通过更换IP或者使用IP代理 来反爬虫 对于验证码只能通过算法或使用Cookie绕过验证码

对网站结构变化

1.在变化前全部爬取 
2.使用脚本对网站结构监测 当变化 就停止爬虫

通过模拟登录

通过代理IP

爬虫环境配置

python库
通用
    1. urllib 提供了对url的操作的功能
    2. Requests 基于1 采用开源协议的HTTP库
    3. urllib3 提供了标准库内没有的特性 线程安全,链接池等
框架
    Scrapy 一个为爬取网站数据 提取结构性数据编写的应用框架

HTML/XML解析器
    lxml C编写的高效库
    Beautiful Soup4 纯python编写 效率低
    

安装mysql数据库
安装MongoDB数据库

静态网页爬取

静态网页是网站建设的基础 通常为纯粹的HTMl格式 也可以包含
一部分的动画 如GIF Flash 滚动字幕等 这些网页的扩展名为.htm,.html

利用urllib3 和 requests 获取网页

关于urllib3 request的配置
点击查看urllib3
import urllib3
        
        # 在这里设置全局的 同下
        http = urllib3.PoolManager()
        url = "http://www.tipdm.com/tipdm/index.html"
        # rq = http.request("GET",url)
        
        # # 返回状态响应码
        # print(rq.status)
        # # 返回响应实体
        # print(rq.data)
        
        # 请求头处理
        # 对于 request() 函数 需要传入headers参数 可以通过定义字典实现
        # User-Agent信息包含了 使用的浏览器 和 使用的系统
        ua = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) Chrome/65.0.3325.181"}
        
        # rq = http.request("GET",url,ua)
        # print(rq.data)
        
        # timeout设置
        # 可以防止由于服务器或者网络问题造成的丢包 可以在GET请求中 加入timeout参数 通常为浮点数 根据需求的不同
        # timeout参数提供了多种设置方法
        # 可以设置 全部的timeout参 也可以 分别设置 连接和读取的timeout参
        # 在PoolManager实例中 可以设置应用全局的 timeout参数
        
        # 设置都为3
        rq = http.request("GET",url,timeout = 3.0)
        print(rq.data)
        # 分别设置为 连接1  读取3
        rq = http.request("GET",url,timeout=urllib3.Timeout(connect=1.0,read=3.0))
        print(rq.data)
        
        # 在这里设置全局的 同下
        # http = urllib3.PoolManager(timeout = 3.0)
        # http = urllib3.PoolManager(timeout = urllib3.Timeout(connect = 1.0,read = 3.0))
        
        
        # 请求重试
        # urllib3 库可以通过 设置request函数的retries参 进行重试控制 默认进行3次重试 以及3次重定向
        # 统一设置
        # http = urllib3.PoolManager(timeout = 3.0,retries = 10)
        
        # http = urllib3.PoolManager(timeout = urllib3.Retry(5,read=4))
        
        # rq = http.request("GET",url,timeout = 3.0,retries = 5)
        # 分别定义重定向 和 重试
        # rq = http.request("GET",url,timeout = 3.0,retries = 5,redirect = 4)
        # 关闭
        # rq = http.request("GET",url,timeout = 3.0,retries = False)
        # 仅关闭重定向
        # rq = http.request("GET",url,timeout = 3.0,redirect = False)

点击查看代码
import urllib3
        
        # 建立链接池
        http = urllib3.PoolManager()
        
        # 设置请求网站
        url = "http://www.tipdm.com/tipdm/index.html"
        
        # 定义请求头
        # google浏览器  windos操作系统
        ua = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) Chrome/65.0.3325.181"}
        
        tm = urllib3.Timeout(connect=1.0,read=4.0)
        
        rq = http.request("GET",url,headers=ua,timeout=tm,retries=5,redirect=4)
        
        print("状态码:",rq.status)
        print("返回主体:",rq.data)

-----------------------------------------------------
        
    关于requests库实现访问网页
        # requests 是一个原生的 http库 比 urllib3 更容易使用
        # 相对于urllib3 requests库 可以发送HTTP/1.1请求
        # 无须手动为url添加查询字串 也不需要对POST数据进行编码
        import chardet
        import requests
        url = "http://www.tipdm.com/tipdm/index.html"
        requests.get(url,**kwargs)
        # 仅一行 就可以完成GET请求
        res = requests.get(url)
        print("状态码:",res.status_code)
        print("编码类型:",res.encoding)
        print("响应头:",res.headers)
        print("网页内容:",res.text)
        
        # 可以手动的更改结果的编码
        # res.encoding = "utf-8"
        # 但是手动的更改编码无法适应全部的网页
        # 所以 可以使用 chardet库 来检测给定的字符串的编码 chardet.detect(byte_str)
        
        # content内是 byte 类型的原始内容
        print(chardet.detect(res.content))
        
        ua = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) Chrome/65.0.3325.181"}
        # 给requests.get() 添加请求头
        res = requests.get(url,headers=ua)
        print("响应头:",res.headers)
        
        # Timeout设置
        res = requests.get(url,headers=ua,timeout=2)
        print("响应头:",res.headers)

完整的requests的get请求
点击查看requests
import chardet
            import requests
            url = "http://www.tipdm.com/tipdm/index.html"
            ua = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) Chrome/65.0.3325.181"}
            # 给requests.get() 添加请求头
            res = requests.get(url,headers=ua,timeout = 2)
            print("响应码:",res.status_code)
            # 是在本电脑的编码
            print("当前页面的编码:",res.encoding)
            # 修改当前页面的编码为 页面本来的编码
            res.encoding = chardet.detect(res.content)['encoding']
            print("修改后的编码:",res.encoding)
            
            print("响应头:",res.headers)
            print("页面内容:",res.text)

解析网页

对网页的解析可以获得网页包含的数据信息 如文本 图片 视频 等
学会使用 Chrome开发者工具查看页面信息
学会正则表达式匹配字符串
学会正则表达式查找页面内容
学会lxml库的etree模块实现获得网页
使用Beautiful Soup4 遍历文档树

Chrome开发者工具

image

源代码: 可设置调试js
    网络: 可以查看页面请求 下载 文件 查看HTTP请求头 响应内容
    性能: 展示页面加载花费时间
    内存: 提供比性能更详细分析
    应用: 检测加载的所有资源
    安全: 调试页面安全 认证问题 

对于爬虫 我们常常使用 元素面板 源代码面板 网络面板


使用正则表达式解析网页s
    python的正则表达式模块 re
    re内的函数: 
    1. compile 将正则字符串转为 Patter匹配对象

    2. match 将输入字符串重头进行匹配 如果无 或者 到达尾部 就返回None 否则获得结果
    3. search 对输入进行扫描 对正则进行匹配 获得结果 没有返回None
    一个是重头开始 一个是整体开始

    4. split 将能够匹配的字符串作为分隔符 分割后返回一个列表
    5. findall 搜索整个字符串 返回一个包含全部可匹配子串的列表
    6. finditer 返回迭代器
    7. sub 替换匹配的子串内容

re模块解析html代码
import re
        import requests
        import chardet
        # 将正则表达式 转化内对象  pattern str类型   flags str类型 |可同时生效
        # flags : re.I 忽略大小写 re.M多行模式  re.S 将.修改为任意匹配
        # re.compile(pattern,flag=0)
        
        # 对整个整个字符串进行烧苗 对输入的正则进行匹配
        # re.search(pattern,string,flags=0)
        
        pat = re.compile(r"\d+")
        # # 返回一个对象
        # print(re.search(pat,"ad12cccc123"))
        # # 返回一个列表 内部有匹配的值
        # print(re.findall(pat,"ad12cccc123"))
        url = "http://www.tipdm.com/tipdm/index.html"
        ua = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) Chrome/65.0.3325.181"}
        
        res = requests.get(url,headers = ua,timeout = 3)
        
        # 转换编码
        res.encoding = chardet.detect(res.content)["encoding"]
        
        title_pattern = r'(?<=<title>).*?(?=</title>)'
        title_com = re.compile(title_pattern,re.M|re.S)
        print(re.search(title_com,res.text).group())
        print(re.findall(title_com,res.text))

Xpath 解析网页
XML路径语言是一门在XML文档查找信息的语言 
Xpath最初被设计搜索XML文档 但是在HTML同样适用
    
    
    # lxml.etree.HTML(text,parser = None,*,base_url=None)
    # text: HTML字符串  parser: HTML解释器  base_url 文档初始url
    
    html = etree.HTML(res.text,parser=etree.HTMLParser(encoding='utf-8'))
    
    # html可以使用类似的正则匹配HTML的内容
    # nodename : 选取nodename节点的全部子节点 /直接子节点 //子孙节点  . 当前节点 ..父节点 @选取属性
    
    # resss = html.xpath('head')
    # print(resss)
    # res = html.xpath('html/head/title')
    # print(res)
    # res = html.xpath('title')
    # print(res)
    
    # xpath 类似前段
    # 谓语  /html/body/div[1] 子节点的第一个div节点  div[last()] div[last()-1]  div[position()<3] div[@id] div[@id="content"]
    
    resss = html.xpath("//title/text()")
    print(resss)

Beautiful Soup解析网页
    
    # Beautiful Soup 是一个可以解析HTMl 或者 XML文件的python库 提供了简单的函数来进行导航 搜索 修改分析树等功能
    # 这个库 非常简单 可以少量代码写出完整应用程序
BeautifulSoup解析html
from bs4 import BeautifulSoup
        import requests
        import chardet
        
        url = "http://www.tipdm.com/tipdm/index.html"
        ua = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) Chrome/65.0.3325.181"}
        res = requests.get(url,headers = ua)
        res.encoding = chardet.detect(res.content)['encoding']
        html = res.text
        
        # soup可以将html转为复杂的树 树内有四种节点  tag navigableSring beautifulsoup comment
        soup = BeautifulSoup(html,'lxml')
        # tag: html中的标签  每次只能获得第一个 除非链式调用
        # tag对象有两个重要的属性 name attributes
        
        # 对于tag标签 可以使用 tag.string 获得其值
        
        
        # 格式化输出
        # print(soup.prettify())
        # 输出 head 标签
        # print(soup.head)
        # 输出 body下的第一个a
        
        # 输出全部的a
        
        
        # 对于bs4 搜索特定的节点 并且获得其中的文本或者连接
        # find_all(name,attrs,recursive,string,limit,**kwargs)
        # name: tag attrs:符合css类名  string匹配这个字符串
        
        # 输出文本中 名为title的子节点
        print(soup.find_all('title'))
        # 输出文本内容
        print(soup.title.string)
        # 输出内容
        print(soup.title.get_text())
        # 找类
        print(soup.find_all('ul',class_='menu'))
        # 找id
        print(soup.find_all(id='menu'))
        
        # 找到ul下的全部的a标签
        tar = soup.ul.find_all('a')
        urls = []
        text = []
        for s in tar:
            urls.append(s.get('href'))
            text.append(s.get_text())
        
        for i in urls:
            print(i)
        
        for j in text:
            print(j)

json与mysql

json:
    json.dump(obj): 转为对象
    json.dumps(obj): 转为字符串


爬取网页 解析网页标题 将数据写入数据库
将数据库和爬虫串联
import pymysql
        conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='kunye666',db='spider',charset='utf8')
        
        # 创建游标
        cursor = conn.cursor()
        # 创建语句
        # sql = '''create table if not exists class (id int(10) primary key auto_increment,name varchar(20) not null,text varchar (20) not null )'''
        # # 执行语句
        # cursor.execute(sql)
        # cursor.execute('show tables')
        
        import requests
        import chardet
        from bs4 import BeautifulSoup
        
        url = "http://www.tipdm.com/tipdm/index.html"
        ua = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) Chrome/65.0.3325.181"}
        # 获得网页内容
        res = requests.get(url,ua,timeout = 3)
        res.encoding = chardet.detect(res.content)['encoding']
        html = res.text
        # 获得网页标题
        soup = BeautifulSoup(html,'lxml')
        target = soup.title.string
        print("标题:",target)
        title = 'tipdm'
        # 网页标题写入表内
        sql = 'insert into class(name,text) values(%s,%s)'
        cursor.execute(sql,(title,target))
        conn.commit()
        
        # 读取数据
        cursor.execute('select * from class')
        # 获得查询结果中的n条记录  fetchmany(n)
        data = cursor.fetchmany()
        print(data)
        conn.close()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值