python爬虫实例详解


Posted in Python onJune 19, 2018

本篇博文主要讲解Python爬虫实例,重点包括爬虫技术架构,组成爬虫的关键模块:URL管理器、HTML下载器和HTML解析器。

爬虫简单架构

python爬虫实例详解

程序入口函数(爬虫调度段)

#coding:utf8
import time, datetime

from maya_Spider import url_manager, html_downloader, html_parser, html_outputer


class Spider_Main(object):
 #初始化操作
 def __init__(self):
  #设置url管理器
  self.urls = url_manager.UrlManager()
  #设置HTML下载器
  self.downloader = html_downloader.HtmlDownloader()
  #设置HTML解析器
  self.parser = html_parser.HtmlParser()
  #设置HTML输出器
  self.outputer = html_outputer.HtmlOutputer()

 #爬虫调度程序
 def craw(self, root_url):
  count = 1
  self.urls.add_new_url(root_url)
  while self.urls.has_new_url():
   try:
    new_url = self.urls.get_new_url()
    print('craw %d : %s' % (count, new_url))
    html_content = self.downloader.download(new_url)
    new_urls, new_data = self.parser.parse(new_url, html_content)
    self.urls.add_new_urls(new_urls)
    self.outputer.collect_data(new_data)

    if count == 10:
     break

    count = count + 1
   except:
    print('craw failed')

  self.outputer.output_html()

if __name__ == '__main__':
 #设置爬虫入口
 root_url = 'http://baike.baidu.com/view/21087.htm'
 #开始时间
 print('开始计时..............')
 start_time = datetime.datetime.now()
 obj_spider = Spider_Main()
 obj_spider.craw(root_url)
 #结束时间
 end_time = datetime.datetime.now()
 print('总用时:%ds'% (end_time - start_time).seconds)

URL管理器

class UrlManager(object):
 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 in self.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.add_new_url(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

网页下载器

import urllib
import urllib.request

class HtmlDownloader(object):

 def download(self, url):
  if url is None:
   return None

  #伪装成浏览器访问,直接访问的话csdn会拒绝
  user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
  headers = {'User-Agent':user_agent}
  #构造请求
  req = urllib.request.Request(url,headers=headers)
  #访问页面
  response = urllib.request.urlopen(req)
  #python3中urllib.read返回的是bytes对象,不是string,得把它转换成string对象,用bytes.decode方法
  return response.read().decode()

网页解析器

import re
import urllib
from urllib.parse import urlparse

from bs4 import BeautifulSoup

class HtmlParser(object):

 def _get_new_urls(self, page_url, soup):
  new_urls = set()
  #/view/123.htm
  links = soup.find_all('a', href=re.compile(r'/item/.*?'))
  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 = {}
  #url
  res_data['url'] = page_url
  #<dd class="lemmaWgt-lemmaTitle-title"><h1>Python</h1>获得标题标签
  title_node = soup.find('dd', class_="lemmaWgt-lemmaTitle-title").find('h1')
  print(str(title_node.get_text()))
  res_data['title'] = str(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, html_content):
  if page_url is None or html_content is None:
   return None

  soup = BeautifulSoup(html_content, '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

网页输出器

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('maya.html', 'w', encoding='utf-8')
  fout.write("<head><meta http-equiv='content-type' content='text/html;charset=utf-8'></head>")
  fout.write('<html>')
  fout.write('<body>')
  fout.write('<table border="1">')
  # <th width="5%">Url</th>
  fout.write('''<tr style="color:red" width="90%">
     <th>Theme</th>
     <th width="80%">Content</th>
     </tr>''')
  for data in self.datas:
   fout.write('<tr>\n')
   # fout.write('\t<td>%s</td>' % data['url'])
   fout.write('\t<td align="center"><a href=\'%s\'>%s</td>' % (data['url'], data['title']))
   fout.write('\t<td>%s</td>\n' % data['summary'])
   fout.write('</tr>\n')
  fout.write('</table>')
  fout.write('</body>')
  fout.write('</html>')
  fout.close()

运行结果

python爬虫实例详解

附:完整代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python解析中国天气网的天气数据
Mar 21 Python
python机器学习实战之树回归详解
Dec 20 Python
Python中pow()和math.pow()函数用法示例
Feb 11 Python
pyqt5的QWebEngineView 使用模板的方法
Aug 18 Python
浅谈python requests 的put, post 请求参数的问题
Jan 02 Python
在Python中表示一个对象的方法
Jun 25 Python
简单了解python的break、continue、pass
Jul 08 Python
Pyinstaller加密打包应用的示例代码
Jun 11 Python
详解Python直接赋值,深拷贝和浅拷贝
Jul 09 Python
Python3中FuzzyWuzzy库实例用法
Nov 18 Python
matplotlib对象拾取事件处理的实现
Jan 14 Python
Django项目在pycharm新建的步骤方法
Mar 02 Python
Python实现的NN神经网络算法完整示例
Jun 19 #Python
python中的二维列表实例详解
Jun 19 #Python
Tensorflow中使用tfrecord方式读取数据的方法
Jun 19 #Python
python3实现SMTP发送邮件详细教程
Jun 19 #Python
Python SVM(支持向量机)实现方法完整示例
Jun 19 #Python
Tensorflow使用tfrecord输入数据格式
Jun 19 #Python
Tensorflow 训练自己的数据集将数据直接导入到内存
Jun 19 #Python
You might like
PHP新手上路(六)
2006/10/09 PHP
PHP中strncmp()函数比较两个字符串前2个字符是否相等的方法
2016/01/07 PHP
利用PHP命令行模式采集股票趋势信息
2016/08/09 PHP
Yii框架批量插入数据扩展类的简单实现方法
2017/05/23 PHP
PHP实现的一致性Hash算法详解【分布式算法】
2018/03/31 PHP
在laravel中实现ORM模型使用第二个数据库设置
2019/10/24 PHP
用ADODB.Stream转换
2007/01/22 Javascript
prettify 代码高亮着色器google出品
2010/12/28 Javascript
jQuery bind事件使用详解
2011/05/05 Javascript
js弹出框轻量级插件jquery.boxy使用介绍
2013/01/15 Javascript
php中给js数组赋值方法
2014/03/10 Javascript
jQuery寻找n以内完全数的方法
2015/06/24 Javascript
JavaScript实现九九乘法表的简单实例
2016/06/07 Javascript
Javascript中的数组常用方法解析
2016/06/17 Javascript
基于JS实现弹出一个隐藏的div窗口body页面变成灰色并且不可被编辑
2016/12/14 Javascript
走进javascript——不起眼的基础,值和分号
2017/02/24 Javascript
详解Vue 2.0封装axios笔记
2017/06/22 Javascript
原生JS实现的轮播图功能详解
2018/08/06 Javascript
vue多层嵌套路由实例分析
2019/03/19 Javascript
Python入门及进阶笔记 Python 内置函数小结
2014/08/09 Python
Python实现对字符串的加密解密方法示例
2017/04/29 Python
详解 Python 读写XML文件的实例
2017/08/02 Python
Python实现霍夫圆和椭圆变换代码详解
2018/01/12 Python
python 对多个csv文件分别进行处理的方法
2019/01/07 Python
Python秒算24点实现及原理详解
2019/07/29 Python
python pycharm的安装及其使用
2019/10/11 Python
去除python中的字符串空格的简单方法
2020/12/22 Python
马来西亚在线购物:POPLOOK.com
2019/12/09 全球购物
2019史上最全Database工程师题库
2015/12/06 面试题
UNIX命令速查表
2012/03/10 面试题
舞蹈教师自荐信
2014/01/27 职场文书
终止劳动合同协议书
2014/04/14 职场文书
大学生社会实践评语
2014/04/25 职场文书
2015年电工工作总结
2015/04/10 职场文书
远程教育集中轮训基层干部培训班学习心得体会
2016/01/09 职场文书
党组织结对共建协议书
2016/03/23 职场文书