深入理解Python分布式爬虫原理


Posted in Python onNovember 23, 2017

首先,我们先来看看,如果是人正常的行为,是如何获取网页内容的。

(1)打开浏览器,输入URL,打开源网页

(2)选取我们想要的内容,包括标题,作者,摘要,正文等信息

(3)存储到硬盘中

上面的三个过程,映射到技术层面上,其实就是:网络请求,抓取结构化数据,数据存储。

我们使用Python写一个简单的程序,实现上面的简单抓取功能。

#!/usr/bin/python 
#-*- coding: utf-8 -*- 
''''' 
Created on 2014-03-16 
 
@author: Kris 
''' 
import urllib2, re, cookielib 
 
def httpCrawler(url): 
  ''''' 
  @summary: 网页抓取 
  ''' 
  content = httpRequest(url) 
  title = parseHtml(content) 
  saveData(title) 
 
def httpRequest(url): 
  ''''' 
  @summary: 网络请求 
  '''  
  try: 
    ret = None 
    SockFile = None 
    request = urllib2.Request(url) 
    request.add_header('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)') 
    request.add_header('Pragma', 'no-cache') 
    opener = urllib2.build_opener() 
    SockFile = opener.open(request) 
    ret = SockFile.read() 
  finally: 
    if SockFile: 
      SockFile.close() 
     
  return ret 
 
def parseHtml(html): 
  ''''' 
  @summary: 抓取结构化数据 
  ''' 
  content = None 
  pattern = '<title>([^<]*?)</title>' 
  temp = re.findall(pattern, html) 
  if temp: 
    content = temp[0] 
   
  return content 
   
def saveData(data): 
  ''''' 
  @summary: 数据存储 
  ''' 
  f = open('test', 'wb') 
  f.write(data) 
  f.close() 
   
if __name__ == '__main__': 
  url = 'http://www.baidu.com' 
  httpCrawler(url)

看着很简单,是的,它就是一个爬虫入门的基础程序。当然,在实现一个采集过程,无非就是上面的几个基础步骤。但是实现一个强大的采集过程,你会遇到下面的问题:

(1)需要带着cookie信息访问,比如大多数的社交化软件,基本上都是需要用户登录之后,才能看到有价值的东西,其实很简单,我们可以使用Python提供的cookielib模块,实现每次访问都带着源网站给的cookie信息去访问,这样只要我们成功模拟了登录,爬虫处于登录状态,那么我们就可以采集到登录用户看到的一切信息了。下面是使用cookie对httpRequest()方法的修改:

ckjar = cookielib.MozillaCookieJar() 
cookies = urllib2.HTTPCookieProcessor(ckjar)     #定义cookies对象 
def httpRequest(url): 
  ''''' 
  @summary: 网络请求 
  '''  
  try: 
    ret = None 
    SockFile = None 
    request = urllib2.Request(url) 
    request.add_header('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)') 
    request.add_header('Pragma', 'no-cache') 
    opener = urllib2.build_opener(cookies)    #传递cookies对象 
    SockFile = opener.open(request) 
    ret = SockFile.read() 
  finally: 
    if SockFile: 
      SockFile.close() 
     
  return ret

(2)编码问题。网站目前最多的两种编码:utf-8,或者gbk,当我们采集回来源网站编码和我们数据库存储的编码不一致时,比如,163.com的编码使用的是gbk,而我们需要存储的是utf-8编码的数据,那么我们可以使用Python中提供的encode()和decode()方法进行转换,比如:

content = content.decode('gbk', 'ignore')   #将gbk编码转为unicode编码 
content = content.encode('utf-8', 'ignore')  #将unicode编码转为utf-8编码

中间出现了unicode编码,我们需要转为中间编码unicode,才能向gbk或者utf-8转换。

(3)网页中标签不完整,比如有些源代码中出现了起始标签,但没有结束标签,HTML标签不完整,就会影响我们抓取结构化数据,我们可以通过Python的BeautifulSoup模块,先对源代码进行清洗,再分析获取内容。

(4)某些网站使用JS来生存网页内容。当我们直接查看源代码的时候,发现是一堆让人头疼的JS代码。可以使用mozilla、webkit等可以解析浏览器的工具包解析js、ajax,虽然速度会稍微慢点。

(5)图片是flash形式存在的。当图片中的内容是文字或者数字组成的字符,那这个就比较好办,我们只要利用ocr技术,就能实现自动识别了,但是如果是flash链接,我们将整个URL存储起来了。

(6)一个网页出现多个网页结构的情况,这样我们如果只是一套抓取规则,那肯定不行,所以需要配置多套模拟进行协助配合抓取。

(7)应对源网站的监控。抓取别人的东西,毕竟是不太好的事情,所以一般网站都会有针对爬虫禁止访问的限制。
一个好的采集系统,应该是,不管我们的目标数据在何处,只要是用户能够看到的,我们都能采集回来。所见即所得的无阻拦式采集,无论是否需要登录的数据都能够顺利采集。大部分有价值的信息,一般都需要登录才能看到,比如社交网站,为了应对登录的网站要有模拟用户登录的爬虫系统,才能正常获取数据。不过社会化网站都希望自己形成一个闭环,不愿意把数据放到站外,这种系统也不会像新闻等内容那么开放的让人获取。这些社会化网站大部分会采取一些限制防止机器人爬虫系统爬取数据,一般一个账号爬取不了多久就会被检测出来被禁止访问了。那是不是我们就不能爬取这些网站的数据呢?肯定不是这样的,只要社会化网站不关闭网页访问,正常人能够访问的数据,我们也能访问。说到底就是模拟人的正常行为操作,专业一点叫“反监控”。

源网站一般会有下面几种限制:

1、一定时间内单个IP访问次数,一个正常用户访问网站,除非是随意的点着玩,否则不会在一段持续时间内过快访问一个网站,持续时间也不会太长。这个问题好办,我们可以采用大量不规则代理IP形成一个代理池,随机从代理池中选择代理,模拟访问。代理IP有两种,透明代理和匿名代理。

2、一定时间内单个账号访问次数,如果一个人一天24小时都在访问一个数据接口,而且速度非常快,那就有可能是机器人了。我们可以采用大量行为正常的账号,行为正常就是普通人怎么在社交网站上操作,并且单位时间内,访问URL数目尽量减少,可以在每次访问中间间隔一段时间,这个时间间隔可以是一个随机值,即每次访问完一个URL,随机随眠一段时间,再接着访问下一个URL。

如果能把账号和IP的访问策略控制好了,基本就没什么问题了。当然对方网站也会有运维会调整策略,敌我双方的一场较量,爬虫必须要能感知到对方的反监控将会对我们有影响,通知管理员及时处理。其实最理想的是能够通过机器学习,智能的实现反监控对抗,实现不间断地抓取。

下面是本人近期正在设计的一个分布式爬虫架构图,如图1所示:

深入理解Python分布式爬虫原理

纯属拙作,初步思路正在实现,正在搭建服务器和客户端之间的通信,主要使用了Python的Socket模块实现服务器端和客户端的通信。如果有兴趣,可以单独和我联系,共同探讨完成更优的方案。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
使用python实现扫描端口示例
Mar 29 Python
Python基于辗转相除法求解最大公约数的方法示例
Apr 04 Python
python数据结构之线性表的顺序存储结构
Sep 28 Python
python实现根据指定字符截取对应的行的内容方法
Oct 23 Python
python基于socket进行端口转发实现后门隐藏的示例
Jul 25 Python
python处理document文档保留原样式
Sep 23 Python
wxpython+pymysql实现用户登陆功能
Nov 19 Python
python  ceiling divide 除法向上取整(或小数向上取整)的实例
Dec 27 Python
Python创建临时文件和文件夹
Aug 05 Python
Python3合并两个有序数组代码实例
Aug 11 Python
小结Python的反射机制
Sep 28 Python
python画条形图的具体代码
Apr 20 Python
Python实现希尔排序算法的原理与用法实例分析
Nov 23 #Python
Python 用Redis简单实现分布式爬虫的方法
Nov 23 #Python
Python3 伪装浏览器的方法示例
Nov 23 #Python
python学习笔记之列表(list)与元组(tuple)详解
Nov 23 #Python
python数字图像处理之高级滤波代码详解
Nov 23 #Python
Python3网络爬虫之使用User Agent和代理IP隐藏身份
Nov 23 #Python
python网络爬虫之如何伪装逃过反爬虫程序的方法
Nov 23 #Python
You might like
Apache设置虚拟WEB
2006/10/09 PHP
PHP生成excel时单元格内换行问题的解决方法
2010/08/26 PHP
CI框架入门之MVC简单示例
2016/11/21 PHP
容易被忽略的JS脚本特性
2011/09/13 Javascript
javascript确认框的三种使用方法
2013/12/17 Javascript
js使用栈来实现10进制转8进制与取除数及余数
2014/06/11 Javascript
JavaScript中的document.referrer在各种浏览器测试结果
2014/07/18 Javascript
jQuery中:file选择器用法实例
2015/01/04 Javascript
js实现背景图片感应鼠标变化的方法
2015/02/28 Javascript
ECMAScript 5中的属性描述符详解
2015/03/02 Javascript
jQuery晃动层特效实现方法
2015/03/09 Javascript
jquery验证邮箱格式并显示提交按钮
2015/11/07 Javascript
微信小程序 http请求详细介绍
2016/10/09 Javascript
原生js实现日期计算器功能
2017/02/17 Javascript
jQuery模拟下拉框选择对应菜单的内容
2017/03/07 Javascript
js前端实现图片懒加载(lazyload)的两种方式
2017/04/24 Javascript
Angular2管道Pipe及自定义管道格式数据用法实例分析
2017/11/29 Javascript
浅谈vue的props,data,computed变化对组件更新的影响
2018/01/16 Javascript
通过实例了解js函数中参数的传递
2019/06/15 Javascript
Webpack中loader打包各种文件的方法实例
2019/09/03 Javascript
利用H5api实现时钟的绘制(javascript)
2020/09/13 Javascript
在Django的模板中使用认证数据的方法
2015/07/23 Python
python中print()函数的“,”与java中System.out.print()函数中的“+”功能详解
2017/11/24 Python
使用django-crontab实现定时任务的示例
2018/02/26 Python
pycharm 主题theme设置调整仿sublime的方法
2018/05/23 Python
使用Python轻松完成垃圾分类(基于图像识别)
2019/07/09 Python
python 实现将Numpy数组保存为图像
2020/01/09 Python
Python代码注释规范代码实例解析
2020/08/14 Python
描述RIP和OSPF区别以及特点
2015/01/17 面试题
司机检讨书
2014/02/13 职场文书
企业法人授权委托书范本
2014/09/23 职场文书
辞职书格式样本
2015/02/26 职场文书
生产设备维护保养制度
2015/08/06 职场文书
pytorch 权重weight 与 梯度grad 可视化操作
2021/06/05 Python
七个非常实用的Python工具包总结
2021/06/15 Python
Python基本知识点总结
2022/04/07 Python