7.实战演练:爬取百度百科1000个页面的数据
1.爬虫实例—分析目标
步骤:
确定目标:确定抓取哪个网站的哪个网页的哪些数据—百度百科python词条页面以及相关词条页面的标题和简介
分析目标:确定抓取策略:url格式限定抓取范围 分析数据格式:分析标题和简介的格式 网页的编码
编写代码:
执行爬虫:进行数据的抓取
1.打开百度百科的页面:确定url,然后点击链接,查看相关词条的url格式,(右键审查元素)
总结:
1.目标:百度百科Python词条相关词条网页—标题和简介
2.入口页:
http://baike.baidu.com/view/21087.htm
3.url格式:词条页面url:/view/125370.html(在任意一个链接上右键审查元素),这不是一个完整的URL.需要在之前补上/baike.baidu.com
4.数据格式:(分别在标题和简介上右键审查元素)
—标题:<dd class=”lemmaWgt-lemmaTitle-title”><h1>****</h1></dd>
—简介:<div class=”lemma_summary”>***</div>
5.页面编码:UTF-8(再页面任意位置审查元素,head标签中有编码格式)
注意:每一个互联网的网站都会不停的升级它的格式,所以定向爬虫也要相应的升级
2.调度程序(关键)
编写爬取百度百科Python词条相关1000个页面数据
1)包和模块的创建:
包:baike_spider
模块:spider_main.py 程序的入口文件
url_manager.py url管理器
html_downloader.py 下载器
html_parser.py 解析器
html_outputer.py 结果收集和输出
2)编写爬虫入口程序:自顶向下的方式
if__name__==”__main__”:
root_url=http://baike.baidu.com/view/21087.htm
obj_spider=SpiderMain()#创建一个spider对象
obj_spider.craw()#开始爬虫
在spider中进行管理器,下载器和解释器以及结果的展示的初始化
在craw中进行爬虫的过程执行:首先把root_url加入new_url列表,然后开始执行爬重循环,只要has_new_url()不为空:首先get_new_url(),然后downloader.download(new_url),然后将获取的html_cont传给parser.parse(),返回new_urls和new_data,并将new_urls加入new_url列表,将new_data存入outputer.collect_data()
最后,将outputer.output_html将结果输出
#coding:utf-8
'''
Created on 2015-12-29
爬虫的总调度程序入口
@author: Administrator
'''
frombaike_spider importurl_manager, html_downloader, html_parser,\
html_outputer
class SpiderMain(object):
def __init__(self):#初始化url管理器,下载器,解释器和输出器
self.urls=url_manager.UrlManger()
self.downloader=html_downloader.HtmlDownloader()
self.parser=html_parser.HtmlParser()
self.outputer=html_outputer.HtmlOutputer()
def craw(self,root_url):
count=1 #记录当前爬取的是第几个url
self.urls.add_new_url(root_url)#首先将入口url添加进url管理器
while self.urls.has_new_url():#开始启动爬虫的循环
try:
new_url=self.urls.get_new_url()
print 'craw %d : %s'%(count,new_url)
html_cont=self.downloader.download(new_url)
new_urls, new_data= self.parser.parse(new_url,html_cont)
self.urls.add_new_urls(new_urls)
self.outputer.collect_data(new_data)
if count==5:
break
count=count+1
except:
print 'craw failed %s' %new_url
self.outputer.output_html()
if__name__=='__main__':
root_url="http://baike.baidu.com/view/21087.htm"#设置爬虫的入口url
obj_spider=SpiderMain()#创建一个spider
obj_spider.craw(root_url)#启动爬虫
3.URL管理器
管理两个列表:new_urls ,old_urls
添加new_url ,添加old_urls
判断是否还有new_url ,获取new_url
#coding:utf-8
'''
Created on 2015-12-29
@author: Administrator
'''
class UrlManger(object):#需要维护两个列表,一个是待爬取的url 一个是已经爬取过的url
def __init__(self):
self.new_urls=set()
self.old_urls=set()
def add_new_url(self,url):
if url is None:
return
if url not in self.new_urls and url not inself.old_urls:
self.new_urls.add(url)
def add_new_urls(self,urls):
if urls is None or len(urls)==0:
return
for url in urls:
self.new_urls.add(url)
def has_new_url(self):
return len(self.new_urls)!=0
def get_new_url(self):
new_url=self.new_urls.pop()
self.old_urls.add(new_url)
return new_url
4.HTML下载器html_downloader
通过urllib2模块对url下载
#coding:utf-8
'''
Created on 2015-12-29
@author: Administrator
'''
import urllib2
class HtmlDownloader(object):
def download(self,url):
if url is None:
return None
response=urllib2.urlopen(url)
if response.getcode()!=200:
return None
return response.read()
5.HTML解析器html_parser
对 html_cont进行解析,调用BeautifulSoup模块,进行解析出新的new_urls和new_data,注意此时解析的url不是完整的url需要进行补全
#coding:utf-8
'''
Created on 2015-12-29
@author: Administrator
'''
from bs4 import BeautifulSoup
import re
import urlparse
class HtmlParser(object):
def _get_new_urls(self, page_url, soup):
new_urls=set()
links=soup.find_all('a',href=re.compile(r"/view/\d+\.htm"))
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, page_url,soup):
res_data={}
res_data['url']=page_url
title_node=soup.find('dd',{"class":"lemmaWgt-lemmaTitle-title"}).find('h1')
res_data['title']=title_node.get_text()
summary_node=soup.find('div',{"class":"lemma-summary"})
res_data['summary']=summary_node.get_text()
return res_data
def parse(self,page_url,html_cont):
if page_url is None or html_contisNone:
return
soup=BeautifulSoup(html_cont,'html.parser',from_encoding='utf-8')
new_urls=self._get_new_urls(page_url,soup)
new_data=self._get_new_data(page_url,soup)
return new_urls,new_data
6.HTML输出器html_outputer
需要将数据写入output.html文件,并且没有的话就创建
维护一个datas的列表,来源为collect_data()函数,输出以表格的形式输出
#coding:utf-8
'''
Created on 2015-12-29
@author: Administrator
'''
class HtmlOutputer(object):
def __init__(self):
self.datas=[]
def collect_data(self,data):
if data is None:
return
self.datas.append(data)
def output_html(self):
fout=open('output.html','w')
fout.write("<html>")
fout.write("<head>")
fout.write("<meta http-equiv='Content-Type' content='text/html;charset=utf-8' />")
fout.write("</head>")
fout.write("<body>")
fout.write("<table border='1',cellspacing='0',color='red'>")
i=0
for data in self.datas:
if i%2==0:
color="#00FFFF"
else:
color="#00DDDD"
fout.write("<tr Bgcolor=%s>" %color)
fout.write("<td> %s </td>" % data['url'])
fout.write("<td> %s </td>" % data['title'].encode('utf-8'))
fout.write("<td> %s </td>" % data['summary'].encode('utf-8'))
fout.write("</tr>")
color=color+"#000002"
i=i+1
fout.write("</table>")
fout.write("</body>")
fout.write("</html>")
fout.close()
7.开始运行爬虫和爬取结果展示
执行spider_main.py就可以咯