Python 网络爬虫程序详解
#!/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天|12天搞定Python网络爬虫,吃里爬外?
人力资源部漂亮的小MM,跑来问我:老陈,数据分析和爬虫究竟是关系呀?说实在的,我真不想理她,因为我一直认为这个跟她的工作关系不大,可一想到她负责我负责部门的招聘工作,我只好勉为其难地跟她说:数据分析, ...
- Python网络爬虫与信息提取笔记
直接复制粘贴笔记发现有问题 文档下载地址//download.csdn.net/download/hide_on_rush/12266493 掌握定向网络数据爬取和网页解析的基本能力常用的 Pytho ...
- Python网络爬虫:空姐网、糗百、xxx结果图与源码
如前面所述,我们上手写了空姐网爬虫,糗百爬虫,先放一下传送门: Python网络爬虫requests.bs4爬取空姐网图片Python爬虫框架Scrapy之爬取糗事百科大量段子数据Python爬虫框架 ...
- Python对Excel操作详解
Python对Excel操作详解 文档摘要: 本文档主要介绍如何通过python对office excel进行读写操作,使用了xlrd.xlwt和xlutils模块.另外还演示了如何通过Tcl ...
- 《精通Python网络爬虫》|百度网盘免费下载|Python爬虫实战
<精通Python网络爬虫>|百度网盘免费下载|Python爬虫实战 提取码:7wr5 内容简介 为什么写这本书 网络爬虫其实很早就出现了,最开始网络爬虫主要应用在各种搜索引擎中.在搜索引 ...
- python之sys模块详解
python之sys模块详解 sys模块功能多,我们这里介绍一些比较实用的功能,相信你会喜欢的,和我一起走进python的模块吧! sys模块的常见函数列表 sys.argv: 实现从程序外部向程序传 ...
- Linux开机启动程序详解
Linux开机启动程序详解我们假设大家已经熟悉其它操作系统的引导过程,了解硬件的自检引导步骤,就只从Linux操作系统的引导加载程序(对个人电脑而言通常是LILO)开始,介绍Linux开机引导的步骤. ...
- Linux开机启动程序详解[转]
Linux开机启动程序详解 我们假设大家已经熟悉其它操作系统的引导过程,了解硬件的自检引导步骤,就只从Linux操作系统的引导加载程序(对个人电脑而言通常是LILO)开始,介绍Linux开机引导的步骤 ...
- linux系统设置服务开机启动3种方法,Linux开机启动程序详解
linux系统设置服务开机启动 方法1:.利用ntsysv伪图形进行设置,利用root登陆 终端命令下输入ntsysv 回车:如下图 方法2:利用命令行chkconfig命令进行设置 简要说明 ...
随机推荐
- NOIP提高组/CSP-S复赛需掌握的算法
1.排序算法(快排.选择.冒泡.堆排序.二叉排序树.桶排序) 2.DFS/BFS 也就是搜索算法,剪枝务必要学! 学宽搜的时候学一下哈希表! 3.树 ①遍历 ②二叉树 ③二叉排序树(查找.生成.删除) ...
- [考试反思]0825NOIP模拟测试30:没落
AB卷,15人. Lrefrain rank#1 179 skyh rank#2 122 116 108 54 42虽说还是不怎么样,但是有好转的迹象. 开卷审题,T1是个(假)期望,感觉也许还可做. ...
- Vue项目中执行npm run dev 不报错也不显示点击的地址链接
问题描述: 输入npm run dev 没有报错也没有显示可以点击的地址链接,如下图: 解决方法: 具体配置: autoOpenBrowser默认为false,改为true.重新 npm run de ...
- go语言教程之浅谈数组和切片的异同
Hello ,各位小伙伴大家好,我是小栈君,上次分享我们讲到了Go语言关于项目工程结构的管理,本期的分享我们来讲解一下关于go语言的数组和切片的概念.用法和区别. 在go语言的程序开发过程中,我们避免 ...
- python——多线程
多线程特点: • 线程的并发是利用cpu上下文的切换(是并发,不是并行) • 多线程执行的顺序是无序的 • 多线程共享全局变量 • 线程是继承在进程里的,没有进程就没有线程 • GIL全局解释器锁 • ...
- 20190806-sed面试题
由于比较难,附上PPT,没事还得看 下载:https://www.lanzous.com/i5cs9aj 密码:arka 1.删除centos7系统/etc/grub2.cfg⽂件中所有以空⽩开头的⾏ ...
- Java线程池中线程的状态简介
首先明确一下线程在JVM中的各个状态(JavaCore文件中) 1.死锁,Deadlock(重点关注) 2.执行中,Runnable(重点关注) 3.等待资源,Waiting on condition ...
- spring+struts2引起的错误被记忆问题
标题表述的比较模糊,详细情况是这样的: 目前开发的一个管理系统,当使用出现异常时会自动跳转到错误页.其处理流程是“发生异常——跳转到错误处理action——错误页”. 但是出现了一个bug,即某个操作 ...
- Oracle基础:数据库操作_数据库事务_表的锁定
数据库操作语句: INSERT INTO 表名[(字段列表)] VALUES ( 表达式列表); 例子:INSERT INTO emp(empno,ename,job,hiredate) VALUES ...
- 【计算机网络】TCP基础知识详解
1. TCP概念相关 [!NOTE] TCP(Transmission Control Protocol),又叫传输控制协议. TCP协议是面向连接的,可靠的,基于字节流的传输协议.在基于 TCP 进 ...