#!/usr/bin/python  #调用python

 from sys import argv  #导入sys是导入python解释器和他环境相关的参数
from os import makedirs,unlink,sep  #os主要提供对系统路径,文件重命名和删除文件所需的函数
  #makedirs是创建递归文件夹的函数。
  #比如说我们要创建一个新的目录,/python/HTML/crawl,但是目前这三个文件夹都不存在,如果使用mkdir命令的话需要使用三次才能完成,
  #但是使用os.makedir只需使用一次就可以创建好整个目录。
  #os.makedirs(os.path.join(os.erviron["HOME"],"python","HTML","crawl")
  #os.unlink(path)删除file路径,和remove()相同。
  #sep os.sep系统用此来分割路径名
from os.path import dirname,exists,isdir,splitext
  #使用os中的这些模块来提取dirname路径名,exists,isdir是文件类型测试,测试是否是一个目录,splitext是将文件名和文件后缀分离。分成目录文件名和后缀两部分。
from string import replace,find,lower  #导入string模块,用于字符串的替换,查找,和小写化。
from htmllib import HTMLParser
from urllib import urlretrieve  #urlretrieve()函数用于将HTML文件整个下载到你的本地硬盘中去。
from urlparse import urlparse,urljoin  #urlparse用于将URL分解成6个元素,而urljoin用于将baseurl和newurl组合在一起
from formatter import DumbWriter,AbstractFormatter  #formatter函数主要用于格式化文本
from cStringIO import StringIO  #调用cStringIO函数对内存中的文件进行处理

  #Retriever类负责从网上下载网页并对每一个文档里面的连接进行分析,如果符合下载原则就添加到“待处理”队列中。
  #从网上下载到的每个主页都有一个与之对应的Retriever实例。Retriever有几个帮助实现功能的方法,分别是:
  #构造器(__init__()),filename(),download()和parseAndGetLinks()。
class Retriever:
  def __init__(self,url):
    #定义构造器,指向当前类的当前实例的引用。self 指向新创建的对象,另外一个参数是url.
    #构造器实例化一个Retriever对象,并且把URL字符串和从filename()返回的与之对应的文件名保存为本地属性。
self.url=url  #将url的值付给self.url
self.file=self.filename(url)
def filename(self,url,deffile="index.html"):  #定义filename方法,涉及另外两个参数,url,deffile,很明显deffile是后缀
parsedurl=urlparse(url,"http:",0)
urlparse(urlstr,defProtsch=None,allowFrag=None),defProtsch定义了缺醒的网络协议和下载方式,allow是一个表示是否允许在URL中使用不完整成分的操作标志。allow_fragment如果是false,即使在URL addressing scheme支持fragment identifiers得情况下fragment identifiers也不允许,默认情况下fragment的默认值是true.
path=parsedurl[1]+parsedurl[2]
从urlparse分离出来的六个元素分别是(prot_shc,net_loc,path,params,query,frag).
parseurl[1]是net_loc,parseurl[2]是path.
和在一起正好是整个路径
ext=splitext(path)
将path分解成目录文件名和后缀标志。
if ext[1]=="":
如果没有文件。ext是一个字符串,ext[0]就是目录文件名,而ext[1]就是后缀名,说明没有后缀
if path[-1]=="/":
并且path是比如说是以我的博客为例,http://blog.csdn.net/yangwenchao1983,分离后path[-1]=3,也就是字符串的最后一个字母,如果是/,说明有文件内容,
path=path+deffile
如果URL没有尾缀的文件名,就用缺性的"index.html“作为文假名,可以说是一个主王爷,上面有各种文件公下载,现在没有合适的文件,我们酒吧index.html作为补充。
else:
path=path+"/"+deffile  #如果是一个完整的文件名,我们需要在后面加上/index.html  如果不含有"/"符号的话,
dir=dirname(path)  #提取path字符串的目录名称
if sep!="/":  #如果文件的分割符不是/
dir=replace(dir,"/",sep)  #将dir中的/替换成分割符,/
if not isdir(dir):  #使用isdir辨别文件类型不是目录。
if exists(dir): unlink(dir)  #如果不是目录文件,就是用unlink移除,
makedirs(dir)  #重新使用makedirs创建目录文件
return path  #返回经过整理的路径
def download(self):  #定义download()方法,使用try...except...来进行异常处理,
try:
retval=urlretrieve(self.url,self.file)
urlretrieve()不像urlopen()那样对URL进行读操作,它只是简单的把位于urlstr处的HTML文件整个下载到你的本地硬盘中去,如果没有给出localfile,它就会把数据保存到一个临时文件中去。很明显,这行程序的意思就是将self.url从望上的某个地方拷贝到硬盘的self.file中去。
except IOError:
如果文件不存在,就会引发IOerror,
retval=("***ERROR: invalid URL "%s"" %\self.url,)
没有在有效的网址上找到这个文件,就将"***ERROR: invalid URL "%s""打印出来
return retval  #返回得到的文件
def parseAndGetLinks(self):
如果上面的的处理没有发现任何错误,就会调用parseAndGetLinks()对新下载打破的主页进行分析,确定对那个主页上的每一个连接应该采取什么样的行动。
self.parser=HTMLParser(AbstractFormatter(DumbWriter(StringIO())))
使用HTMLParser的方法进行处理,StringIO是从内存中读取数据,DumbWriter将事件流转换为存文本文档。
self.parser.feed(open(self.file).read())
将self.file文件打开并且一次性读入上面定义的的文件中去
self.parser.close()  #关闭文件
return self.parser.anchorlist  #返回地址和日期 class Crawler:
Crawler由三个数据项组成,这三个数据项是由构造器在实例化阶段报存在这里的。
count = 0   #静态下载主页计数器
def __init__(self,url):
self.q=[url]
第一个数据是q,这是一个有下载连接组成的队列,这个清单在执行过程中是会变化的,没处理一个主页它就缩短一次,而在各下载主页中发现一个新的连接就会被加长。
self.seen=[]
Crawler的另外两个数据项包括seen-这是我们已经下载过的全体连接所组成的一个列表;
self.dom=urlparse(url)[1]
把主连接的域名报存在dom中,用这个值核对后续连接是否属于这同一个区域。 def getPage(self,url):
getPage()方法用第一个连接实例化出一个Retriever对象,从她开始进行后续的处理。
r=Retriever(url)
使用上面定义过得Retriever类,付给r。
retval=r.download()  #下载网页连接,
if retval[0]=="*":     print retval,"...skipping parse"
return
Crawler.count=Crawler.count+1
Crawler还有一个静态数据叫做count。这个计数器的作用就是记录我们呢已经从望红色那个下载到的对象的个数,每成功下载一个主页,就让它增加一个数。
print "\n(",Crawler.count,")"
print "URL:",url
print "FILE:",retval[0]
self.seen.append(url) links=r.parseAndGetLinks()
for eachLink in Links:
if eachLink[:4]!="http" and find(eachLink,"://")==-1
print "*",eachLink,
以下链接将被忽略,不会被添加到待处理队列里去的:属于另外一个域的连接,已经被下载过得链接,已经放入待处理队列里去的连接或者是"mailto:"连接。
if find(lower(eachLink),"mailto:")!=-1:应该是超连接
print "...discard,mailto link"
contine
if eachlink not in self.seen:
if find(eachLink,self.dom)==-1:
print "...discarded,not in domain"
else:
if eachLink not in self.q:
self.q.append(eachLink)
print "...new,aded to Q"
else:
print "...discarded,already in Q"
else:
print "...discarded,already processed"
def go(self):
while self.q:
url=self.q.pop()
self.getPage(url)
def main():
if len(argv)>1:
url=argv[1]
else:
try:
url=raw_input("Enter starting URL:")
except(KeyboardInterrupt,EOFError):
url=""
if not url: return
robot=Crawler(url)
robot.go() if __name__=="__main__":
main() main()只有在这个脚本程序在直接被调用时才会执行,它是程序的出发点,其他导入了crawl.py的模块需要明确的调用main()才能开始处理。要让main()开始执行,需要给它一个URL,如果已经在一个命令行给出URL(例如我们直接调用这个脚本程序的时候),它就会从给定的URL起开始运行;否则,脚本程序将进入交互模式,提示用户输入一个URL。有了初始连接之后,程序将对Crawler类进行实例化并开始执行。

Python 网络爬虫程序详解的更多相关文章

  1. 第1天|12天搞定Python网络爬虫,吃里爬外?

    人力资源部漂亮的小MM,跑来问我:老陈,数据分析和爬虫究竟是关系呀?说实在的,我真不想理她,因为我一直认为这个跟她的工作关系不大,可一想到她负责我负责部门的招聘工作,我只好勉为其难地跟她说:数据分析, ...

  2. Python网络爬虫与信息提取笔记

    直接复制粘贴笔记发现有问题 文档下载地址//download.csdn.net/download/hide_on_rush/12266493 掌握定向网络数据爬取和网页解析的基本能力常用的 Pytho ...

  3. Python网络爬虫:空姐网、糗百、xxx结果图与源码

    如前面所述,我们上手写了空姐网爬虫,糗百爬虫,先放一下传送门: Python网络爬虫requests.bs4爬取空姐网图片Python爬虫框架Scrapy之爬取糗事百科大量段子数据Python爬虫框架 ...

  4. Python对Excel操作详解

      Python对Excel操作详解 文档摘要: 本文档主要介绍如何通过python对office excel进行读写操作,使用了xlrd.xlwt和xlutils模块.另外还演示了如何通过Tcl   ...

  5. 《精通Python网络爬虫》|百度网盘免费下载|Python爬虫实战

    <精通Python网络爬虫>|百度网盘免费下载|Python爬虫实战 提取码:7wr5 内容简介 为什么写这本书 网络爬虫其实很早就出现了,最开始网络爬虫主要应用在各种搜索引擎中.在搜索引 ...

  6. python之sys模块详解

    python之sys模块详解 sys模块功能多,我们这里介绍一些比较实用的功能,相信你会喜欢的,和我一起走进python的模块吧! sys模块的常见函数列表 sys.argv: 实现从程序外部向程序传 ...

  7. Linux开机启动程序详解

    Linux开机启动程序详解我们假设大家已经熟悉其它操作系统的引导过程,了解硬件的自检引导步骤,就只从Linux操作系统的引导加载程序(对个人电脑而言通常是LILO)开始,介绍Linux开机引导的步骤. ...

  8. Linux开机启动程序详解[转]

    Linux开机启动程序详解 我们假设大家已经熟悉其它操作系统的引导过程,了解硬件的自检引导步骤,就只从Linux操作系统的引导加载程序(对个人电脑而言通常是LILO)开始,介绍Linux开机引导的步骤 ...

  9. linux系统设置服务开机启动3种方法,Linux开机启动程序详解

    linux系统设置服务开机启动 方法1:.利用ntsysv伪图形进行设置,利用root登陆 终端命令下输入ntsysv 回车:如下图     方法2:利用命令行chkconfig命令进行设置 简要说明 ...

随机推荐

  1. Linux的目录介绍

    Linux的目录介绍 Linux系统以目录来组织和管理系统中的所有文件.Linux系统通过目录将系统中所有的文件分级.分层组织在一起,形成了Linux文件系统的树型层次结构.以根目录 “/” 为起点, ...

  2. IIS中如何设置域名

    如何在IIS中设置域名: 1,想好我们想要配置的本地域名,我们以www.baidu.com为例. 2,打开系统盘,一般默认的系统盘为C盘,打开:C:\Windows\System32\drivers\ ...

  3. 学习笔记13_第三方js控件&EasyUI使用

    第三方UI包使用思路: 1.先映入各种JS包,包含JS版本包,第三方CSS包,第三方主JS包,第三方语言包. 2.确定要做什么,是对话框还是表格.3.根据Demo和目的,在<body>内, ...

  4. [2018-01-12] python 当天学习笔记

    Python模块 Python欧快(Moudule),是一个Python文件,以.py结尾,包含了Python对象定义和Python语句. 模块让你能够有逻辑地组织你的Python代码段. 把相关的代 ...

  5. 深入了解 Java Resource && Spring Resource

    在Java中,为了从相对路径读取文件,经常会使用的方法便是: xxx.class.getResource(); xxx.class.getClassLoader().getResource(); 在S ...

  6. 正睿OI集训游记

    什么嘛....就是去被虐的... 反正就是难受就是了.各种神仙知识点,神仙题目,各式各样的仙人掌..... 但是还是学会了不少东西...... 应该是OI生涯最后一次集训了吧.... 这次的感言还是好 ...

  7. Mybatis自定义TypeHandler解决特殊类型转换问题

    我们知道,Java和MySQL中的数据类型是不同的,Java中除了基本数据类型,还有对象. 有时候使用MySQL存储数据,或者从MySQL中读取数据时,会有一些特殊需求

  8. C语言:互质

    今天遇到一道奇怪的程序题,和平常的不同.同样都是互质,但是一般的题目都是判断两个数字是否互质,但这道题则是给定一个数字n,要求输出所有小于等于n的与n互质的数,题目已经在下面给出: 质数与互质概念不是 ...

  9. 创建基于OData的Web API - Knowledge Builder API, Part IV: Write Controller

    基于上一篇<创建基于OData的Web API - Knowledge Builder API, Part III:Write Model and Controller>,新创建的ODat ...

  10. MySQL的安装+可视化工具+JDBC的增删改查

    1.Mysql和可视化工具的安装 安装包网上有很多资源.这里推荐一个我一直在用的学习网站,上面有提供安装包和详细的说明. http://how2j.cn/k/mysql/mysql-install/3 ...