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模块
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):
while self.url_manager.has_new_url():
count =
0
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 =
'http://pythonhosted.org/PyPDF2/index.html'
spider = spider_main(root_url)
spider.run()
url_manager模块
class url_manager():
'''管理爬取到的链接地址'''
def __init__(self, root_url):
self.new_urls = set()
self.old_urls = set()
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'''
self.url = self.new_urls.pop()
self.old_urls.add(self.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模块
import urllib2
class html_downloader():
"""html下载器,使用python自带的urllib2模块进行下载"""
def download(self, url):
self.html = urllib2.urlopen(url)
return self.html.read()
html_parser模块
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
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 = set()
links = self.soup.find_all(
'a', class_ =
'reference internal', href = re.compile(
'.html'))
for link
in links:
new_url = link[
'href']
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模块
class html_outputer():
'''html下载器'''
def output(self, url, html_cont):
'''将获取的html输出为html文件'''
url = str(url)
index = url.rfind(
'/')
html_name = url[index+
1:]
self.html_file = open(html_name,
'w')
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文件放入即可。
转载请注明原文地址: https://ju.6miu.com/read-19716.html