一个简单的爬虫程序(爬取百度百科关于python的一千个页面)
2017-07-28 08:41
726 查看
最近学了点python基础,本着练手的目的跟着网上一个教程写了一个简单的爬虫程序。python入门还是很轻松的,整个过程也很顺利,几乎算是一次就成功了。
1.爬虫架构及工作流程
一个爬虫程序可以分为四个基本模块,总调度端,URL管理器,网页下载器以及网页解析器。
总调度段负责程序的启动,停止以及监视程序的运行进度。
URL管理器负责管理已经爬取过的URL和未爬取过的URL,它将未爬取过的网页URL发送给网页下载器并将该URL从为爬取URL列表删除。
网页下载器负责下载网页内容,转换成字符串形式(本程序中)发送给网页解析器。
网页解析器负责从爬取的网页内容中提取有价值的数据,本程序中有价值的数据为,网页中的URL以及词条名和词条简介。
2.各模块的实现
2.1 URL管理器的实现
网页URL可以存放到内存中(以set()的形式),MySQL数据库中以及redis缓存数据库中(大型项目)。本项目的URL以set()形式存放在内存中。
代码:
2.2 网页下载器的实现
有三种方法下载网页
1.下载最简单的网页(无需登录验证,没有加密…)
response = urllib.request.urlopen(url, data=None, timeout)
url: 需要打开的网址
data:Post提交的数据
timeout:设置网站的访问超时时间
page = response.read()
page = page.decode(‘utf-8’)#设置编码
2.先获取一个请求对象:urllib.request.Request(url, data=None, headers={}, method=None)
可以给包装请求对象设置header包装请求对象
header的参数
User-Agent :这个头部可以携带如下几条信息:浏览器名和版本号、操作系统名和版本号、默认语言
Referer:可以用来防止盗链,如果REFER的信息来自其他网站则禁止访问所需要的资源
Connection:表示连接状态,记录Session的状态。
request.add_header(‘user_agent’, ‘Mozilla/5.0’) 将程序伪装成火狐浏览器
3.处理一些特殊情景
HTTPCookieProcessor 登录验证问题
ProxyHandler 处理代理问题
HTTPRedirectHandler 处理会自动跳转的网页
(还没接触到,以后再说)
本程序使用的第一种方式,代码:
3.网页解析器的实现
用到了BeautifulSoup第三方插件,实现这个功能时要审查待爬取的网页,找到自己要爬取的内容编码,便签,用来筛选数据。代码:
4.数据输出
将数据输出为html格式
5.程序调度
按顺序调用以上各个方法就好了,代码:
1.爬虫架构及工作流程
一个爬虫程序可以分为四个基本模块,总调度端,URL管理器,网页下载器以及网页解析器。
总调度段负责程序的启动,停止以及监视程序的运行进度。
URL管理器负责管理已经爬取过的URL和未爬取过的URL,它将未爬取过的网页URL发送给网页下载器并将该URL从为爬取URL列表删除。
网页下载器负责下载网页内容,转换成字符串形式(本程序中)发送给网页解析器。
网页解析器负责从爬取的网页内容中提取有价值的数据,本程序中有价值的数据为,网页中的URL以及词条名和词条简介。
2.各模块的实现
2.1 URL管理器的实现
网页URL可以存放到内存中(以set()的形式),MySQL数据库中以及redis缓存数据库中(大型项目)。本项目的URL以set()形式存放在内存中。
代码:
class UrlManager(object): def __init__(self): #初始化两个url集合 self.new_urls=set()#存放未爬取过的url self.old_urls=set()#存放已爬取过的url def add_new_url(self,url):#单个添加 if url is None: return #如果是空的则不进行操作 if url not in self.new_urls and url not in self.old_urls:#全新的url self.new_urls.add(url) def has_new_url(self):#判断是否有未爬取的url return len(self.new_urls)!=0 def get_new_url(self): new_url = self.new_urls.pop()#从未怕去的url列表获取一个并移除 self.old_urls.add(new_url) return new_url def add_new_urls(self,urls):#批量添加 if urls is None or len(urls)==0: return for url in urls: self.add_new_url(url)
2.2 网页下载器的实现
有三种方法下载网页
1.下载最简单的网页(无需登录验证,没有加密…)
response = urllib.request.urlopen(url, data=None, timeout)
url: 需要打开的网址
data:Post提交的数据
timeout:设置网站的访问超时时间
page = response.read()
page = page.decode(‘utf-8’)#设置编码
2.先获取一个请求对象:urllib.request.Request(url, data=None, headers={}, method=None)
可以给包装请求对象设置header包装请求对象
header的参数
User-Agent :这个头部可以携带如下几条信息:浏览器名和版本号、操作系统名和版本号、默认语言
Referer:可以用来防止盗链,如果REFER的信息来自其他网站则禁止访问所需要的资源
Connection:表示连接状态,记录Session的状态。
request.add_header(‘user_agent’, ‘Mozilla/5.0’) 将程序伪装成火狐浏览器
3.处理一些特殊情景
HTTPCookieProcessor 登录验证问题
ProxyHandler 处理代理问题
HTTPRedirectHandler 处理会自动跳转的网页
(还没接触到,以后再说)
本程序使用的第一种方式,代码:
def download(self,url): if url is None: return None request1 =urllib.request.urlopen(url) if request1.getcode() !=200:#请求失败 return None return request1.read()
3.网页解析器的实现
用到了BeautifulSoup第三方插件,实现这个功能时要审查待爬取的网页,找到自己要爬取的内容编码,便签,用来筛选数据。代码:
def get_new_urls(self, page_url, soup): new_urls = set() # https://baike.baidu.com/item/Python links = soup.find_all('a',href=re.compile(r"/item/\S"))#查找页面中新的词条url for link in links: new_url = link['href'] new_full_url = urllib.parse.urljoin(page_url, new_url) new_urls.add(new_full_url) return new_urls def get_new_data(self, page_url, soup): res_data = {} res_data['url'] = page_url #<dd class="lemmaWgt-lemmaTitle-title"><h1>Python</h1> title_node = soup.find('dd', class_="lemmaWgt-lemmaTitle-title").find('h1') res_data['title'] = title_node.get_text() #<div class="lemma-summary" label-module="lemmaSummary"> summary_node = soup.find('div',class_="lemma-summary") res_data['summary'] = summary_node.get_text() return res_data def parse(self,page_url,cont): print('开始解析') if page_url is None or cont is None: return soup = BeautifulSoup(cont,'html.parser',from_encoding='utf-8') print('soup') new_urls = self.get_new_urls(page_url,soup) new_data = self.get_new_data(page_url,soup) return new_urls,new_data
4.数据输出
将数据输出为html格式
def collect_data(self,data): if data is None: return None self.datas.append(data)#将爬取的数据集合起来 def output_html(self): fout = open('d:/output.html','w',encoding='utf-8') fout.write("<html>") fout.write("<body>") fout.write("<table>") fout.write("<tr>") fout.write("<td>%s</td>"%'链接') fout.write("<td>%s</td>"%'词条') fout.write("<td>%s</td>"%'简介') fout.write("</tr>") for data in self.datas: if data is None: return None fout.write("<tr>") fout.write("<td>%s</td>" % data['url']) fout.write("<td>%s</td>" % data['title']) fout.write("<td>%s</td>" % data['summary']) fout.write("</tr>") fout.write("</html>") fout.write("</body>") fout.write("</table>")
5.程序调度
按顺序调用以上各个方法就好了,代码:
class SpiderMain(object): def __init__(self): self.url = url_manager.UrlManager() self.downloader = html_downloader.HtmlDownLoader() self.parser = html_parser.HtmlParser() self.outputer = html_outputer.OutPuter() def craw(self, root_url): count = 1 #记录当前爬取的是第几个url self.url.add_new_url(root_url)#把初始url添加到url管理器 while self.url.has_new_url():#当管理器里仍有未爬取url时 try: new_url=self.url.get_new_url()#从管理器中拿出一个url print('craw %d:%s'%(count,new_url)) html_cont=self.downloader.download(new_url)#下载这个url网页的内容 new_urls,new_data = self.parser.parse(new_url,html_cont)#得到新的url列表,和爬取到的数据 self.url.add_new_urls(new_urls) #将新的url添加到管理器,注意于添加root_url的方法不同 self.outputer.collect_data(new_data)#收集数据 if count==1000:#只爬取1000条 break count+=1 except: print('爬取失败') self.outputer.output_html()#将收集的数据输出 if __name__ == '__main__': root_url='https://baike.baidu.com/item/Python' obj_spider = SpiderMain() obj_spider.craw(root_url)#启动爬虫程序
相关文章推荐
- 不断重构:关于一个简单的爬虫小程序
- 一个简单的python爬虫,抓取单个页面的图片
- 一个简单的python爬虫程序 爬取豆瓣热度Top100以内的电影信息
- 一个简单的python爬虫程序
- 实践项目十:爬取百度百科Python词条相关1000个页面数据(慕课简单爬虫实战)
- python学习笔记:"爬虫+有道词典"实现一个简单的英译汉程序
- Python开发简单爬虫(二)---爬取百度百科页面数据
- 一个简单的python爬虫程序
- Python源码分析2 - 一个简单的Python程序的执行
- 一个简单的根据行数对大文件进行分片的python程序
- python3.2 一个简单的socket 程序
- 由一个简单的客户端间TCP/UDP通信程序引发的关于设计模式的思考
- 小程序大问题,MSDN中一个小小示例所带来的疑问,一个关于DataList的一个简单应用
- 一个简单的管理Web站点文件的页面程序(修改版)
- 用python写一个简单的去除源程序代码中行号的程序
- windows下 python 关于管通道(程序回显)处理的一个小例子
- 用Python写一个小小的爬虫程序
- 用Python写的一个简单的端口扫描程序
- 一个简单的Web爬虫程序
- 《Applications=Code+Markup》读书札记(2)——创建一个简单的 WPF 程序的代码结构及关于 Window 实例位置设置问题