python3网络爬虫开发实战_笔记

发布 : 2018-04-01 分类 : python 浏览 :

python3网络爬虫开发实战_笔记


《python3网络爬虫开发实战》 –崔庆才著

原文出处 https://germey.gitbooks.io/python3webspider/content/

window平台相关笔记

开发环境配置

  • python 官网安装python3
  • Anaconda安装
  • 清华大学镜像

  • 会用到的包

    • pip安装 : pip install 包名
    • 源码安装 : 通过git下载源代码,进入文件目录 执行 python3 setup.py install
    • requests 请求包
    • selenium 是一个自动化测试包
      • 需要浏览器驱动文件,并添加至环境变量
      • ChromeDriver selenium用来驱动Chrome浏览器的驱动程序
      • GeckoDriver selenium用来驱动Firefox浏览器的驱动程序
      • PhantomJS 是一个无界面的、可脚本编程的webkit浏览器引擎 api接口说明
    • aiohttp 异步H请求 pip install aiohttp
    • 解析库
      • lxml 解析html和xml的库,支持xpath,解析效率高效 pip install lxml
      • beautifulsoup 解析html和xml的库 pip install beautifulsoup
      • pyquery 同样强大的网页解析工具 pip install pyquery
    • tesserocr

      OCR 即Option Character Recognition,光学识别符。tesserocr是python的一个OCR识别库,但其实是对tesseract的封装,所以也需要安装tesseract。 pip install 。。。。
    • web库

      • flask 是一个轻量级的文本服务程序 pip install flask

        测试
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        from flask import Flask
        app = Flask(__name__)

        @app.route("/")
        def hello():
        return "hello world"

        if __name__ == "__main__":
        app.run()
        ```
        * tornado 是一个支持异步的web框架,通过使用非阻塞I/O流,它可以支持成千上万的开放连接,效率非常高 `pip install tornado`
        <br>测试

      import tornado.ioloop
      import tornado.web

      class MainHandler(tornado.web.RequestHandler):

      def get(self):
          self.write("hello world")
      

      def make_app():

      return tornado.web.Application([
          (r"/",MainHandler),
      ])
      

      if name == “main“:

      app = make_app()
      app.listen(8888)
      tornado.ioloop.IOloop.current().start()
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
          *   App爬取相关的库
      * [Charles](https://www.charlesproxy.com/download) 是一个网络抓包工具,相比Fiddler,功能更加强大
      <br>注: 抓https需要安装证书
      * mitmproxy 是一个支持http和https的抓包程序,类似Fiddler、Charles的功能,不过它通过控制台的形式操作
      * mitmdump 它是mitmproxy的命令行接口,可以利用它来对接python脚本
      * mitmweb 是一个web程序,可以通过它清除的观察mitmproxy捕获的请求
      <br>`pip install mitmproxy` 或 https://github.com/mitmproxy/mitmproxy/releases/
      <br>注: 抓https需要安装证书
      * [Appium](https://github.com/appium/appium-desktop/releases) 是移动端的自动化测试工具,类似于前面所说的Selenium

      #### `数据读写`
      * 按照换行将question、 author、 answer写入文本整体以50个'='分隔
      ```
      with open('explore.txt', 'a', encoding='utf-8') as file:
      file.write('\n'.join([question, author, answer]))
      file.write('\n' + '=' * 50 + '\n')
  • json数据需要用双引号包围,不能使用单引号,若使用如下形式,则会出现错误:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import json

    str = '''
    [{
    'name': 'Bob',
    'gender': 'male',
    'birthday': '1992-10-18'
    }]
    '''
    data = json.loads(str)

    >>>json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 3 column 5 (char 8)

    因为这里数据用单引号来包围,loads()方法解析失败

  • csv文件的读写

    1
    2
    3
    4
    5
    6
    7
    8
    import csv

    with open('data.csv', 'w') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(['id', 'name', 'age'])
    writer.writerow(['10001', 'Mike', 20])
    writer.writerow(['10002', 'Bob', 22])
    writer.writerow(['10003', 'Jordan', 21])
    • 对于写入文件后会出现空行的解决 open('data.csv','w',newline='')
    • 如果想修改列与列之间的分隔符,可以传入delimiter参数,其代码如下:csv.writer(csvfile, delimiter=' ')
    • writerows写入多行
    • 字典读写
      1
      2
      3
      4
      fieldnames = ['id', 'name', 'age']
      writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
      writer.writeheader()
      writer.writerow({'id': '10001', 'name': 'Mike', 'age': 20})

数据库

  • 关系数据库

    • 原子性(atomicity) 事务是一个不可分割的工作单位,事务中包括的诸操作要么全做,要么全不做
    • 一致性(consistency) 事务必须使数据库从一个一致性状态变到另一个一致性状态。
    • 隔离性(isolation) 一个事务的执行不能被其他事务干扰,即一个事物内部的操作及使用的数据
    • 持久性(durability) 持续性也称永久性(permanence),指一个事务一旦提交,他对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响
    1
    2
    3
    4
    5
    6
    try:
    cursor.execute(sql)
    db.commit()
    except:
    db.rollback()
    db.close()
    • 什么是事务,为何用事务?

      保证数据的一致性和完整性,例子:银行存钱

  • 非关系型数据库

    • 键值存储数据库:代表有Redis、Voldemort和Oracle BDB等。
    • 列存储数据库:代表有Cassandra、HBase和Riak等。
    • 文档型数据库:代表有CouchDB和MongoDB等。
    • 图形数据库:代表有Neo4J、InfoGrid和Infinite Graph等。
    • mongodb
      • insert_one()和insert_many()方法来分别插入单条记录和多条记录
      • find_one()或find()方法进行查询
      • count()计数、sort()排序、skip()偏移
      • create_index()索引操作 或者 collection.ensure_index(‘user_name’, unique=True)
    • redis
      • 数据类型: 键、字符串、列表(可重复)、有序集合、无序集合、散列
      • 相应增删改查

        利用Redis维护代理池,Scrapy-Redis分布式架构,利用Redis实现布隆过滤

异步抓取

  • ajax抓取

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var xmlhttp;
    if (window.XMLHttpRequest) {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
    } else {// code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function() {
    if (xmlhttp.readyState==4 && xmlhttp.status==200) {
    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
    }
    }
    xmlhttp.open("POST","/ajax/",true);
    xmlhttp.send();
    • 随着网站的复杂度提升,越来越多的网站内容请求都是通过ajax请求的。
    • 可通过浏览器开发者模式进行观察 XHR请求 或者 script请求
    • XHR是正常的ajax请求,而script是jsonp跨域访问的请求,目前微服务架构中需要跨域访问资源,故而将数据作为js对象进行传输

页面渲染

  • selenium

    • 延时等待
    1. time.sleep()
    2. 隐士等待 implicitly_wait()
    3. 显式等待
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.support import expected_conditions as EC
      browser = webdriver.Chrome()
      browser.get('https://www.taobao.com/')
      wait = WebDriverWait(browser, 10)
      input = wait.until(EC.presence_of_element_located((By.ID, 'q')))
      button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search')))
      print(input, button)

    指定要查找的节点,然后指定一个最长等待时间,如果在规定时间里加载出了这个节点,就返回要查找的节点;如果到了规定时间依然没有加载出该节点,则抛出异常

    • 前进与后退
    1
    2
    3
    4
    browser.get('https://www.python.org/')
    browser.back()
    time.sleep(1)
    browser.forward()
    • Splash 是一个JavaScript渲染服务,是一个带有HTTP API的轻量级浏览器,同时它对接了Python中的Twisted和QT库。利用它,我们同样可以实现动态渲染页面的抓取

      利用Splash,我们可以实现如下功能:
      异步方式处理多个网页渲染过程;
      获取渲染后的页面的源代码或截图;
      通过关闭图片渲染或者使用Adblock规则来加快页面渲染速度;
      可执行特定的JavaScript脚本;
      可通过Lua脚本来控制页面渲染过程;
      获取渲染的详细过程并通过HAR(HTTP Archive)格式呈现。
      接下来,我们来了解一下它的具体用法。

验证码

  • 验证码识别

    • 图形验证码
      利用tesserocr库识别简单图片

      1
      2
      3
      4
      5
      6
      import tesserocr
      from PIL import Image

      image = Image.open('code.jpg')
      result = tesserocr.image_to_text(image)
      print(result)
当图片有多余的线条等干扰时,需要额外的处理,如:转灰度,二值化...


**利用Image对象的convert()方法参数传入L,即可将图片转化为灰度图像**,如: 

    
1
2
image = image.convert('L')
image.show()
**传入1即可将图片进行二值化处理**
1
2
image = image.convert('1')
image.show()
还可以指定二值化的阙值,上面的方法采用的是默认阙值127,不过我们不能直接转化原图,要将原图转化为灰度图像,然后在制定二值化阙值。如:
1
2
3
4
5
6
7
8
9
10
11
12
image = image.convert('L')
#threshold代表二值化阙值
threshold = 80
table = []
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)

image = image.point(table,'1')
image.show()
本文作者 : 对六
原文链接 : http://duiliuliu.github.io/2018/04/01/2018-04-01-python3网络爬虫开发实战_笔记/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

你我共勉!

微信

微信

支付宝

支付宝

留下足迹