python 爬虫 爬取PyPDF2的官方在线文档
2017-04-04 19:56
369 查看
python 爬虫 爬取PyPDF2的官方在线文档
从学python开始就知道爬虫了,不过也仅限于知道。这段时间学习GNU Radio,官网的教程介绍都需要FQ才能看到,太麻烦。就起了用爬虫把所有网页全部下载的想法。这里的话,由于我这边没有FQ,就随便找了python的模块PyPDF2,爬了它的在线文档。把整个过程详细记录下。第一步,确定逻辑关系
所谓爬虫,就是模拟人浏览网页行为的自动化程序。为了以后的爬取其他文档时方便修改,所以将整个爬虫分为5个模块。爬虫入口和主调度模块(spider_main),url管理模块(url_manager),html下载模块(html_downloader),html分析模块(html_parser)和输出模块(html_outputer)。它们之间的通信逻辑如下:Created with Raphaël 2.1.0爬虫调度模块爬虫调度模块url管理模块url管理模块html下载模块html下载模块html分析模块html分析模块是否有未爬取url否,爬取结束。是,返回一个未爬取url发送url下载好的网页代码html_cont发送html_cont新的待爬取urls和本页上需要的数据将新的待爬取urls放入url管理模块重复以上步骤,直到url管理模块中没有未爬取url
第二步,搭建框架
根据第一步的逻辑架构,搭建框架:spdier_main模块
# -*- coding=utf-8 -*- from url_manager import url_manager from html_downloader import html_downloader from html_parser import html_parser from html_outputer import html_outputer class spider_main(): '''爬虫入口和调度模块''' def __init__(self, root_url): '''root_url为爬虫的起始地址 实例url管理器,html下载器,分析器,输出器 ''' self.root_url = root_url self.url_manager = url_manager(self.root_url) self.html_downloader = html_downloader() self.html_parser = html_parser() self.html_outputer = html_outputer() def run(self): # 爬虫的主调度程序 # 具体步骤为:判断url管理器中起否有未爬取url # -> 如果没有,则退出while循环,输出网页 / 如果有,url管理器返回一个未爬取page_url # -> 将page_url传给html下载器进行下载 # -> 将下载结果html_cont传给html分析器进行分析,获取想要的数据(new_data)和新的待爬取的url(new_urls) # -> 将new_urls传递给url管理器 # -> 将获取的数据保存为网页 # -> 重复循环,直到url管理器中没有未爬取url while self.url_manager.has_new_url(): #count用于记录出错的网页个数 count = 0 #try,except语句用于跳过爬取过程中出现的异常 try: self.page_url = self.url_manager.get_new_url() self.html_cont = self.html_downloader.download(self.page_url) self.new_urls = self.html_parser.parse(self.page_url, self.html_cont) self.url_manager.add_new_urls(self.new_urls) self.html_outputer.output(self.page_url, self.html_cont) except: self.count += 1 print('NO.%d, url = %s failed' % (count, self.page_url)) print 'finished' if __name__ == '__main__': #root_url为爬虫入口页 root_url = 'http://pythonhosted.org/PyPDF2/index.html' spider = spider_main(root_url) spider.run()
url_manager模块
# -*- coding=utf-8 -*- class url_manager(): '''管理爬取到的链接地址''' def __init__(self, root_url): #未爬取url,类型为集合,可以自动去除相同项 self.new_urls = set() #已爬取url self.old_urls = set() #将起始url放入未爬取url集合中 self.new_urls.add(root_url) def has_new_url(self): '''有未爬取的url,则返回True,否则返回False''' return len(self.new_urls) != 0 def get_new_url(self): '''返回一个未爬取的url''' #随机删除未爬取链接地址中的一个,并返回给url变量 self.url = self.new_urls.pop() #将url变量放入已爬取链接地址集合中 self.old_urls.add(self.url) #返回url变量 return self.url def add_new_url(self, url): '''如果url变量非空,且未在已爬取url集合中个,则在未爬取url集合中加入新的url''' if (not url is None) and (not url in self.old_urls): self.new_urls.add(url) def add_new_urls(self, urls): '''如果urls集合非空,则调用add_new_url函数将urls添加入未爬取url集合''' if not urls is None: for url in urls: self.add_new_url(url)
html_downloader模块
# -*- coding=utf-8 -*- import urllib2 class html_downloader(): """html下载器,使用python自带的urllib2模块进行下载""" def download(self, url): self.html = urllib2.urlopen(url) return self.html.read()
html_parser模块
# -*- coding=utf-8 -*- from bs4 import BeautifulSoup import urlparse import re class html_parser(): '''html分析器''' def parse(self, page_url, html_cont): if page_url is None or html_cont is None: return #构造DOM树,from_encoding的值由具体的网页选用的编码方法决定 #这是首页的网页代码 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> #from_encoding的值即为charset的值 self.soup = BeautifulSoup(html_cont, 'html.parser', from_encoding='utf-8') new_urls = self.get_new_urls(page_url) return new_urls def get_new_urls(self, page_url): '''从指定页面获取页面中所包含的新的urls''' if page_url is None: return #new_urls用于存放获取的urls new_urls = set() #使用正则表达式进行匹配 links = self.soup.find_all('a', class_ = 'reference internal', href = re.compile('.html')) for link in links: new_url = link['href'] #new_url只是正常网址的最后一部分,需要与当前页网址进行拼接后才能正常访问 new_full_url = urlparse.urljoin(page_url, new_url) new_urls.add(new_full_url) return new_urls def get_new_data(self, html_content): '''用于获取指定的数据''' pass
html_outputer模块
# -*- coding=utf-8 -*- class html_outputer(): '''html下载器''' def output(self, url, html_cont): '''将获取的html输出为html文件''' #获取html文件名 url = str(url) index = url.rfind('/') html_name = url[index+1:] #写模式打开一个html文件 self.html_file = open(html_name, 'w') #写入html代码 self.html_file.write(html_cont) #关闭文件 self.html_file.close()
第三步,修修补补
将每个模块新建一个同名python文件,复制进去,放在一个文件夹中,直接运行spider_main.py 即可在当前文件夹看到下载好的网页。但文件的格式和在线浏览有很大不同,原因是没有同步下载css样式表。
用浏览器打开对应网址,进入开发者模式,network标签,按F5刷新后,保存加载的css文件,查看网页代码发现:
<link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css"> <link rel="stylesheet" href="_static/pygments.css" type="text/css">
css文件保存在网页所在文件夹的子文件夹_static中,新建_static文件夹,将css文件放入即可。
相关文章推荐
- python爬虫 BeautifulSoup4官方文档
- Json官方在线文档
- Python:语音处理,实现在线朗读RFC文档或本地文本文件
- Python3.2官方文档教程- 列表
- Python3.2官方文档教程--方法定义--关键字参数
- Python官方3.2文档教程--方法定义-默认参数值
- ORACLE官方在线文档-有时间大家好好阅读阅读
- Python3.2 官方文档教程--列表
- Python3.2官方文档教程--数字
- centos6.4 编译安装boost.python 1.54--来自官方文档
- Python3.2官方文档教程--其余参数形式
- python内建函数【from官方文档】
- 一个简易的网页爬虫,可用于下载在线API文档
- python 在线文档和下载地址
- Python3.2官方文档教程--字符串
- Python:语音处理,实现在线朗读RFC文档或本地文本文件
- python官方文档
- 转 python内置正则表达式(re)模块官方文档简要中文版
- Python3.2官方文档教程-流程控制语句(if,for,pass)
- Python3.2 官方文档教程---编码风格