Python分布式爬虫原理[通俗易懂]

转载请注明出处:http://blog.csdn.net/yiliumu/article/details/21335245首先,我们先来看看,如果是人正常的行为,是如何获取网页内容的。(1)打开浏览器,输入URL,打开源网页(2)选取我们想要的内容,包括标题,作者,摘要,正文等信息(3)存储到硬盘中上面的三个过程,映射到技术层面上,其实就是:网络请求,抓取结构化数据,数据存

大家好,又见面了,我是你们的朋友全栈君。

转载请注明出处:http://blog.csdn.net/yiliumu/article/details/21335245

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

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


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


(3)存储到硬盘中




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


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

[python] 
view plain  
copy

 
在CODE上查看代码片
派生到我的代码片

  1. #!/usr/bin/python  
  2. #-*- coding: utf-8 -*-  
  3. ”’ 
  4. Created on 2014-03-16 
  5.  
  6. @author: Kris 
  7. ”’  
  8. import urllib2, re, cookielib  
  9.   
  10. def httpCrawler(url):  
  11.     ”’ 
  12.     @summary: 网页抓取 
  13.     ”’  
  14.     content = httpRequest(url)  
  15.     title = parseHtml(content)  
  16.     saveData(title)  
  17.   
  18. def httpRequest(url):  
  19.     ”’ 
  20.     @summary: 网络请求 
  21.     ”’    
  22.     try:  
  23.         ret = None  
  24.         SockFile = None  
  25.         request = urllib2.Request(url)  
  26.         request.add_header(‘User-Agent’‘Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)’)  
  27.         request.add_header(‘Pragma’‘no-cache’)  
  28.         opener = urllib2.build_opener()  
  29.         SockFile = opener.open(request)  
  30.         ret = SockFile.read()  
  31.     finally:  
  32.         if SockFile:  
  33.             SockFile.close()  
  34.           
  35.     return ret  
  36.   
  37. def parseHtml(html):  
  38.     ”’ 
  39.     @summary: 抓取结构化数据 
  40.     ”’  
  41.     content = None  
  42.     pattern = ‘<title>([^<]*?)</title>’  
  43.     temp = re.findall(pattern, html)  
  44.     if temp:  
  45.         content = temp[0]  
  46.       
  47.     return content  
  48.       
  49. def saveData(data):  
  50.     ”’ 
  51.     @summary: 数据存储 
  52.     ”’  
  53.     f = open(‘test’‘wb’)  
  54.     f.write(data)  
  55.     f.close()  
  56.       
  57. if __name__ == ‘__main__’:  
  58.     url = ‘http://www.baidu.com’  
  59.     httpCrawler(url)  



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

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

[python] 
view plain  
copy

 
在CODE上查看代码片
派生到我的代码片

  1. ckjar = cookielib.MozillaCookieJar()  
  2. cookies = urllib2.HTTPCookieProcessor(ckjar)         #定义cookies对象  
  3. def httpRequest(url):  
  4.     ”’ 
  5.     @summary: 网络请求 
  6.     ”’    
  7.     try:  
  8.         ret = None  
  9.         SockFile = None  
  10.         request = urllib2.Request(url)  
  11.         request.add_header(‘User-Agent’‘Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)’)  
  12.         request.add_header(‘Pragma’‘no-cache’)  
  13.         opener = urllib2.build_opener(cookies)       #传递cookies对象  
  14.         SockFile = opener.open(request)  
  15.         ret = SockFile.read()  
  16.     finally:  
  17.         if SockFile:  
  18.             SockFile.close()  
  19.           
  20.     return ret  

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

[python] 
view plain  
copy

 
在CODE上查看代码片
派生到我的代码片

  1. content = content.decode(‘gbk’‘ignore’)      #将gbk编码转为unicode编码  
  2. 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分布式爬虫原理[通俗易懂]

图1

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/126547.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 基于USB数据采集卡(DAQ)与IO模块的热电阻温度采集「建议收藏」

    思迈科华针对热电阻温度传感器温度采集的方案热电阻简介这里主要介绍一下铂热电阻,Pt100是铂热电阻,它的阻值跟温度的变化成正比。PT100的阻值与温度变化关系为:当PT100温度为0℃时它的阻值为100欧姆,在100℃时它的阻值约为138.5欧姆。它的工业原理:当PT100在0摄氏度的时候,它的阻值为100欧姆,它的阻值会随着温度上升而成匀速增长。国标热电阻主要接线方式有三种:二线制:在热电阻的两端各连接一根导线来引出电阻信号的方式叫二线制:这种引线方法很简单,但由于连接导线必然存在引线电阻R,电阻

    2022年4月7日
    54
  • 零基础学Java(10)面向对象-使用LocalDate类完成日历设计

    零基础学Java(10)面向对象-使用LocalDate类完成日历设计前言在我们完成这个日历设计前,需要了解Java中的预定义类LocalDate的一些用法语法LocalDate.now()//2022-07-01会构造一个新对象,表示构造这个对象时的日期。

    2022年8月7日
    10
  • 浅析linux内核中的idr机制

    idr在linux内核中指的就是整数ID管理机制,从本质上来说,这就是一种将整数ID号和特定指针关联在一起的机制。这个机制最早是在2003年2月加入内核的,当时是作为POSIX定时器的一个补丁。现在,

    2021年12月27日
    43
  • mysql中ltrim用法_MySQL LTRIM()用法及代码示例

    mysql中ltrim用法_MySQL LTRIM()用法及代码示例LTRIM MySQL 中的此函数用于从字符串中删除前导空格 用法 LTRIM str 参数 如上所述 它接受一个参数 如下所述 str 我们要从中删除前导空格的字符串 返回值 截断所有前导空格后 它将返回一个字符串 示例 1 使用 LTRIM 函数删除给定字符串的所有前导空格 SELECT geeksforgeek AsOriginalSt LTRIM gee

    2025年6月27日
    1
  • SpringSecurity权限管理系统实战—一、项目简介和开发环境准备

    SpringSecurity权限管理系统实战—一、项目简介和开发环境准备SpringSecurity实战一—项目简介和开发环境准备一、简介​ 在企业应用中,认证和授权是非常重要的一部分内容,业界最出名的两个框架就是大名鼎鼎的Shiro和SpringSecurity。本次我选取的是和SpringBoot更好兼容的SpringSecurity。

    2025年6月7日
    2
  • 2022Android SDK下载与安装

    2022Android SDK下载与安装一、下载sdk:https://www.androiddevtools.cn找个合适的位置解压双击“SDKManager.exe”,启动SDKManager安装工具我们可以通过有AndroidSDK的国内镜像服务器来下载安装,这里推荐几个:1、中科院开源协会镜像站地址:IPV4/IPV6:http://mirrors.opencas.ac.cn端口:802、北京化工大学镜像服务器地址:IPv4:http://ubuntu.buct.edu.cn/端口:80IPv

    2022年7月19日
    18

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号