热门标签 | 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标签的函数。


     

















    推荐阅读
    • 根据最新发布的《互联网人才趋势报告》,尽管大量IT从业者已转向Python开发,但随着人工智能和大数据领域的迅猛发展,仍存在巨大的人才缺口。本文将详细介绍如何使用Python编写一个简单的爬虫程序,并提供完整的代码示例。 ... [详细]
    • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
    • 技术分享:从动态网站提取站点密钥的解决方案
      本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
    • 本文基于刘洪波老师的《英文词根词缀精讲》,深入探讨了多个重要词根词缀的起源及其相关词汇,帮助读者更好地理解和记忆英语单词。 ... [详细]
    • 深入解析Android自定义View面试题
      本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
    • 优化ListView性能
      本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
    • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
    • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
    • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
    • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
    • 深入理解Tornado模板系统
      本文详细介绍了Tornado框架中模板系统的使用方法。Tornado自带的轻量级、高效且灵活的模板语言位于tornado.template模块,支持嵌入Python代码片段,帮助开发者快速构建动态网页。 ... [详细]
    • 深入理解Cookie与Session会话管理
      本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
    • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
      本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
    • 本文探讨了在不使用服务器控件的情况下,如何通过多种方法获取并修改页面中的HTML元素值。除了常见的AJAX方式,还介绍了其他可行的技术方案。 ... [详细]
    • 本文介绍如何使用Python进行文本处理,包括分词和生成词云图。通过整合多个文本文件、去除停用词并生成词云图,展示文本数据的可视化分析方法。 ... [详细]
    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社区 版权所有