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中的魔法方法深入理解
Jul 09 Python
python如何实现远程控制电脑(结合微信)
Dec 21 Python
python 采集中文乱码问题的完美解决方法
Sep 27 Python
python操作xlsx文件的包openpyxl实例
May 03 Python
Python统计python文件中代码,注释及空白对应的行数示例【测试可用】
Jul 25 Python
Python GUI布局尺寸适配方法
Oct 11 Python
对numpy中数组转置的求解以及向量内积计算方法
Oct 31 Python
python 使用值来排序一个字典的方法
Nov 16 Python
Python multiprocessing多进程原理与应用示例
Feb 28 Python
PyTorch实现ResNet50、ResNet101和ResNet152示例
Jan 14 Python
python时间序列数据转为timestamp格式的方法
Aug 03 Python
Django配置跨域并开发测试接口
Nov 04 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/11/19 PHP
PHP 判断常量,变量和函数是否存在
2009/04/26 PHP
php数组函数序列之array_intersect() 返回两个或多个数组的交集数组
2011/11/10 PHP
支持中文字母数字、自定义字体php验证码代码
2012/02/27 PHP
PHP中开启gzip压缩的2种方法
2015/01/31 PHP
PHPExcel读取EXCEL中的图片并保存到本地的方法
2015/02/14 PHP
PHP使用SOAP扩展实现WebService的方法
2016/04/01 PHP
Laravel中unique和exists验证规则的优化详解
2018/01/28 PHP
TP5框架安全机制实例分析
2020/04/05 PHP
实用javaScript技术-屏蔽类
2006/08/15 Javascript
一个简单的js树形菜单
2011/12/09 Javascript
jQuery ReferenceError: $ is not defined 错误的处理办法
2013/05/10 Javascript
js获取元素到文档区域document的(横向、纵向)坐标的两种方法
2013/05/17 Javascript
jquery 设置style:display的方法
2015/01/29 Javascript
jQuery拖拽排序插件制作拖拽排序效果(附源码下载)
2016/02/23 Javascript
ECMAScript6轮播图实践知识总结
2016/08/17 Javascript
JavaScript队列、优先队列与循环队列
2016/11/14 Javascript
Bootstrap导航条学习使用(一)
2017/02/08 Javascript
5分钟打造简易高效的webpack常用配置
2017/07/04 Javascript
解决vue点击控制单个样式的问题
2018/09/05 Javascript
vue实现百度搜索功能
2020/12/28 Javascript
[48:52]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第一局
2016/02/25 DOTA
Python实现国外赌场热门游戏Craps(双骰子)
2015/03/31 Python
python转换字符串为摩尔斯电码的方法
2015/07/06 Python
使用pip发布Python程序的方法步骤
2018/10/11 Python
对python特殊函数 __call__()的使用详解
2019/07/02 Python
Django设置Postgresql的操作
2020/05/14 Python
伦敦最著名的老字号百货公司:Selfridges(塞尔福里奇百货)
2016/07/25 全球购物
英国护发和美妆在线商店:Klip Shop
2019/03/24 全球购物
Ibatis中如何提高SQL Map的性能
2013/05/11 面试题
秋天的雨教学反思
2014/04/27 职场文书
基层党组织整改方案
2014/10/25 职场文书
中学生勤俭节约倡议书
2015/04/29 职场文书
有关水浒传的读书笔记
2015/06/25 职场文书
导游词之清晏园
2019/11/22 职场文书
MySQL root密码的重置方法
2021/04/21 MySQL