您的位置:首页 > 编程语言 > Python开发

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文件放入即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: