热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python爬虫Demo

1爬虫功能:爬取某域名下所有网页,比如爬取python文档 https:docs.python.orgzh-cn3 ,爬取之后,












1 爬虫功能:


  爬取某域名下所有网页,比如爬取python文档 https://docs.python.org/zh-cn/3/ ,爬取之后,获取离线文档


       


 


 


2 代码实现


开发环境: python3.6



import os
import sys
import http.client #2.7版本为httplib
import urllib.request
import formatter
import io


from html.parser import HTMLParser

class Retriever(object):
__slots__ = (\'url\', \'file\')

def __init__(self,url):
self.url, self.file
= self.get_url_file(url)

def get_url_file(self, url, default = \'index.html\'):
#\'Create usable local filename from URL\'
parsed = urllib.request.urlparse(url)
host
= parsed.netloc.split(\'@\')[-1].split(\':\')[0]
print(\'retriever host: %s\' %host)
filepath
= \'%s%s\' %( host, parsed.path)
if not os.path.splitext(parsed.path)[1]:
filepath
= os.path.join(filepath, default)
print(\'retriever filepath: %s\' % filepath)
linkdir
= os.path.dirname(filepath)
if not os.path.isdir(linkdir):
if os.path.exists(linkdir):
os.unlink(linkdir)
os.makedirs(linkdir)
return url, filepath

def download(self):
#\'Download URL to specific named file\'
try:
retval
= urllib.request.urlretrieve(self.url,self.file)
except (IOError,http.client.InvalidURL) as e:
retval ( (
\'***ERROR: bad URL "%s" %s\') %(self.url, e))
return retval

def parse_links(self):
class AnchorParser(HTMLParser):
def handle_starttag(self, tag, attrs):
if tag != \'a\':
return
if not hasattr(self , \'data\'):
self.data
= []
for attr in attrs:
if attr[0] == \'href\':
self.data.append(attr[
1])

f
= open(self.file, \'r\', encoding="UTF-8")
data
= f.read()
f.close()
parser
= AnchorParser()
parser.feed(data)
parser.close()
#output( (urllib.request.join(self.url, x) for x in parser.data ) )
if not hasattr(parser, \'data\'):
return []
return parser.data

class Crawler(object):
count
= 0
def __init__(self, url):
self.q
= [url]
self.seen
= set()
parsed
= urllib.request.urlparse(url)
host
= parsed.netloc.split(\'@\')[-1].split(\':\')[0]
print("host: %s" %host)
#self.dom = \'.\'.join(host.split(\'.\')[-2:])
self.dom = host
print("dom: %s" %self.dom)

def get_page(self, url, media=False):
r
= Retriever(url)
fname
= r.download()[0]
print(\'donwload file name: %s\' %fname)
if fname[0] == \'*\':
print(fname + \'...skipping parse\')
return
Crawler.count
+= 1;
print("(%d,URL:%s, FILE:%s)" %(Crawler.count, url, fname))
self.seen.add(url)
ftype
= os.path.splitext(fname)[1]
if ftype not in (\'.html\', \'htm\'):
return
print(r.parse_links())

for link in r.parse_links():
if link.startswith(\'mailto:\'):
print(\'...discarded, mailto link\')
continue
if not media:
ftype
= os.path.splitext(link)[1]
if ftype in (\'.mp3\', \'.mp4\', \'.m4v\', \'.wav\'):
print( \'...discard, media file\')
continue
if ftype in (\'.epub\'):
print(\'...discard, epub file\')
continue
if not link.startswith(\'http://\') and not link.startswith(\'https://\'):
link
= urllib.request.urljoin(url, link)
print(\'*\', link)
if link not in self.seen:
if self.dom not in link:
print(\'...discard,not in domain\')
else:
if link not in self.q:
self.q.append(link)
print(\'...new, added to Q\')
else:
print(\'...discard, already in Q\')
else:
print(\'...discarded, already processed\')


def go(self, media = False):
#\'Process next page in queue (if any) \'
while self.q:
url
= self.q.pop()
self.get_page(url, media)

def main():
if len(sys.argv) > 1:
url
= sys.argv[1]
else:
try:
url
= input(\'Entry starting URL: \')
except(KeyboardInterrupt, KeyError):
url
= \'\'
if not url:
return
if not url.startswith(\'http://\') and \
not url.startswith(\'https://\'):
url
= \'http://%s/\' %url

print(\'start url: %s\' %url )

robot
= Crawler(url)
robot.go()



if __name__ == \'__main__\':
main()


 


 


 


3使用包包和函数


os.path


os.path.splitext


用法: os.path.splitext(“文件路径”)    分离文件名扩展名;默认返回(fname,fextension)元组,可做分片操作


os.path.join


用法: 接两个或更多的路径名组件


                         1.如果各组件名首字母不包含’/’,则函数会自动加上


         2.如果有一个组件是一个绝对路径,则在它之前的所有组件均会被舍弃


         3.如果最后一个组件为空,则生成的路径以一个’/’分隔符结尾


os.path.dirname


语法:os.path.dirname(path) 
功能:去掉文件名,返回目录 


os.path.unlink


os.unlink(path) 方法用于删除文件,如果文件是一个目录则返回一个错误。


 


urllib.request


urllib.request.urlretrieve


python3中urllib.request模块提供的urlretrieve()函数。urlretrieve()方法直接将远程数据下载到本地。


urlretrieve(url, filename=None, reporthook=None, data=None)


参数url:下载链接地址
参数filename:指定了保存本地路径(如果参数未指定,urllib会生成一个临时文件保存数据。)
参数reporthook:是一个回调函数,当连接上服务器、以及相应的数据块传输完毕时会触发该回调,我们可以利用这个回调函数来显示当前的下载进度。
参数data:指post导服务器的数据,该方法返回一个包含两个元素的(filename, headers) 元组,filename 表示保存到本地的路径,header表示服务器的响应头


html.parse.HTMLParser


HTMLParser 类



  1. HTMLParser.feed(data):接收一个字符串类型的HTML内容,并进行解析


  2. HTMLParser.close():当遇到文件结束标签后进行的处理方法。如果子类要复写该方法,需要首先调用HTMLParser累的close()


  3. HTMLParser.reset():重置HTMLParser实例,该方法会丢掉未处理的html内容


  4. HTMLParser.getpos():返回当前行和相应的偏移量


  5. HTMLParser.handle_starttag(tagattrs):对开始标签的处理方法。例如,参数tag指的是div,attrs指的是一个(name,Value)的列表


  6. HTMLParser.handle_endtag(tag):对结束标签的处理方法。例如
,参数tag指的是div

  • HTMLParser.handle_data(data):对标签之间的数据的处理方法。test,data指的是“test”


  • HTMLParser.handle_comment(data):对HTML中注释的处理方


  • 当然了,使用Python自带的HTMLParser还是比较麻烦的,需要手写处理Html标签的函数。


     

















    推荐阅读
    author-avatar
    掌纹clear贡
    这个家伙很懒,什么也没留下!
    Tags | 热门标签
    RankList | 热门文章
    PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有