Python最基础的应用就是爬虫。
本文是看了慕课网一个视频教程后根据该教程写的一个爬虫实例。这个教程讲的还是挺好的,建议刚开始学Python的童鞋可以看看。
目标:抓取百度百科Python词条相关词条网页——标题和简介
入口:https://baike.baidu.com/item/Python
URL格式:
--词条页面URL:/item/...
数据格式:
--标题:<dd class="lemmaWgt-lemmaTitle-title"><h1>Python</h1>
--简介:<div class="lemma-summary" label-module="lemmaSummary">
页面编码:utf-8
开发环境:
1、安装JRE环境:下载jdk-8u161-windows-x64,安装即可
2、安装Eclipse软件:从蒲公英上下载eclipse-java-oxygen-R-win32-x86_64,直接打开exe就是
3、安装Python 2.X:在官网下载Python 2.7.14,默认安装到C盘,之后配置环境变量---将“C:\Python27”、“C:\Python27\Scripts”添加到path路径,然后将python.exe改成python2.exe
4、环境配置:打开Eclipse》Windows》Preferences》Interpreters》Python Interpreter,在右侧新建,在弹出来的窗口第二个对话框选择python2.exe,一直确定就好。
在Eclipse中新建pyDev Project,命名imooc;
右键imooc,新建pyDev package,命名baike_spider;
右键baike_spider,新建pyDev module,分别命名spider_main、url_manager、html_downloader、html_parser、html_outputer。
1、调度程序:spider_main
# coding:utf-8
from baike_spider import url_manager,html_downloader,html_parser,html_outputer
class SpiderMain(object):
def __init__(self): //初始化方法
self.urls = url_manager.UrlManager() //url管理器
self.downloader = html_downloader.HtmlDownloader() //网页下载器
self.parser = html_parser.HtmlParser() //解析器
self.outputer = html_outputer.HtmlOutputer() //内容输出器
def craw(self, root_url):
count = 1 //计数器
self.urls.add_new_url(root_url) //添加根网址到url管理器
while self.urls.has_new_url(): //开始循环
try:
new_url = self.urls.get_new_url() //取第一个url
print 'craw %d : %s' % (count,new_url) //输出url
html_cont = self.downloader.download(new_url) //下载网页内容
new_urls,new_data = self.parser.parse(new_url,html_cont) //获取新的url和价值数据
self.urls.add_new_urls(new_urls) //添加新的url到url管理器
self.outputer.collect_data(new_data) //收集价值数据
if count == 1000:
break
count = count + 1
except:
print 'craw failed'
self.outputer.output_html() //输出数据到网页
print 'finished!'
if __name__=="__main__":
root_url = "https://baike.baidu.com/item/Python" //原始根网址
obj_spider = SpiderMain() //主程序入口
obj_spider.craw(root_url) //爬虫启动
2、url管理器:url_manager
# coding:utf-8
class UrlManager(object):
def __init__(self): //初始化方法
self.new_urls = set() //未爬URL容器
self.old_urls = set() //已爬URL容器
def add_new_url(self,url): //单个URL存储方法
if url is None:
return
if url not in self.new_urls and url not in self.old_urls:
self.new_urls.add(url)
def add_new_urls(self,urls): //多个URL存储方法
if urls is None or len(urls) == 0:
return
for url in urls:
self.new_urls.add(url)
def has_new_url(self): //判断是否还有未爬URL
return len(self.new_urls) != 0
def get_new_url(self): //获取一个未爬URL
new_url = self.new_urls.pop()
self.old_urls.add(new_url)
return new_url
3、网页下载:html_downloader
# coding:utf-8
import urllib2
class HtmlDownloader(object):
def download(self,url): //下载网页方法
if url is None:
return None
response = urllib2.urlopen(url) //请求数据
if response.getcode() != 200: //状态码如果等于200,说明请求成功
return None
return response.read() //读取数据
4、解释器:html_parser
# coding:utf-8
from bs4 import BeautifulSoup
import urlparse
import re
class HtmlParser(object):
def parse(self,page_url,html_cont): //解释器方法:page_url是网址参数,html_cont是网页内容参数
if page_url is None or html_cont is None:
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
def _get_new_urls(self, page_url, soup): //新网址获取方法,这个要根据具体网址信息来设计,不是一成不变的
new_urls = set() //网址容器
links = soup.find_all('a',href=re.compile(r"/item/")) //获取标签为a、包含“/item/”的链接信息(这个信息事实上是残缺的)
for link in links: //这里用到正则表达式
new_url = link['href']
new_full_url = urlparse.urljoin(page_url,new_url) //我们这里将残缺的网址信息和网址参数合并作为新的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
5、输出:html_outputer
# coding:utf-8
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') //新建一个.html文件
fout.write("<html>") //将爬到的内容输出为html
fout.write("<body>") //所以这里输出为html表格形式
fout.write("<table>")
for data in self.datas:
fout.write("<tr>")
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>")
fout.write("</table>")
fout.write("</body>")
fout.write("</html>")
fout.close()
运行spider_main,刷新baike_spider项目,会看到新生成的output.html;找到该本地文件,直接用浏览器打开,就能看到爬虫抓取的数据信息.