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虚拟环境Virtualenv使用教程
May 18 Python
Python中函数eval和ast.literal_eval的区别详解
Aug 10 Python
python字典操作实例详解
Nov 16 Python
python实现BackPropagation算法
Dec 14 Python
python3 读写文件换行符的方法
Apr 09 Python
对Python中9种生成新对象的方法总结
May 23 Python
Python Opencv实现图像轮廓识别功能
Mar 23 Python
Python基于scipy实现信号滤波功能
May 08 Python
python 对任意数据和曲线进行拟合并求出函数表达式的三种解决方案
Feb 18 Python
Python如何把Spark数据写入ElasticSearch
Apr 18 Python
Python如何对XML 解析
Jun 28 Python
Python扫描端口的实现
Jan 25 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
深入分析使用mysql_fetch_object()以对象的形式返回查询结果
2013/06/05 PHP
php ci框架中加载css和js文件失败的原因及解决方法
2014/07/29 PHP
PHP中file_exists使用中遇到的问题小结
2016/04/05 PHP
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
2013/01/23 Javascript
杨氏矩阵查找的JS代码
2013/03/21 Javascript
JavaScript模块随意拖动示例代码
2014/05/27 Javascript
给js文件传参数(详解)
2014/07/13 Javascript
JS获取网页图片name属性的方法
2015/04/01 Javascript
js中unicode转码方法详解
2015/10/09 Javascript
js弹出对话框方式小结
2015/11/17 Javascript
jQuery 1.9.1源码分析系列(十五)动画处理之缓动动画核心Tween
2015/12/03 Javascript
有关jquery与DOM节点操作方法和属性记录
2016/04/15 Javascript
Vue分页组件实例代码
2017/04/17 Javascript
AngularJS使用ui-route实现多层嵌套路由的示例
2018/01/10 Javascript
Koa2 之文件上传下载的示例代码
2018/03/29 Javascript
微信小程序内拖动图片实现移动、放大、旋转的方法
2018/09/04 Javascript
详解Vue实战指南之依赖注入(provide/inject)
2018/11/13 Javascript
vue动态设置页面title的方法实例
2020/08/23 Javascript
浅谈Vue开发人员的7个最好的VSCode扩展
2021/01/20 Vue.js
python实现求两个字符串的最长公共子串方法
2018/07/20 Python
对IPython交互模式下的退出方法详解
2019/02/16 Python
python中几种自动微分库解析
2019/08/29 Python
初次部署django+gunicorn+nginx的方法步骤
2019/09/11 Python
Django xadmin开启搜索功能的实现
2019/11/15 Python
python使用SQLAlchemy操作MySQL
2020/01/02 Python
Python socket处理client连接过程解析
2020/03/18 Python
使用HTML5的File实现base64和图片的互转
2013/08/01 HTML / CSS
Baby Tulai澳大利亚:美国婴儿背带品牌
2018/10/15 全球购物
科颜氏法国官网:Kiehl’s法国
2019/08/20 全球购物
分布式数据库需要考虑哪些问题
2013/12/08 面试题
小学毕业典礼演讲稿
2014/09/09 职场文书
师德师风自我评价范文
2014/09/11 职场文书
2014年党员学习“三严三实”思想汇报
2014/09/15 职场文书
司法局群众路线教育实践活动整改措施思想汇报
2014/10/13 职场文书
2016年先进教师个人事迹材料
2016/02/26 职场文书
人事部:年度述职报告范文
2019/07/12 职场文书