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正则表达式使用范例分享
Dec 04 Python
Python简单实现查找一个字符串中最长不重复子串的方法
Mar 26 Python
python中使用print输出中文的方法
Jul 16 Python
Python使用修饰器进行异常日志记录操作示例
Mar 19 Python
20行python代码的入门级小游戏的详解
May 05 Python
详解Python odoo中嵌入html简单的分页功能
May 29 Python
python的pytest框架之命令行参数详解(上)
Jun 27 Python
Python 实现顺序高斯消元法示例
Dec 09 Python
在pytorch中对非叶节点的变量计算梯度实例
Jan 10 Python
python实现一次性封装多条sql语句(begin end)
Jun 06 Python
python不同版本的_new_不同点总结
Dec 09 Python
Python实现灰色关联分析与结果可视化的详细代码
Mar 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中UNIX_TIMESTAMP()函数与php中time()函数的区别
2013/06/24 PHP
php+mysql查询优化简单实例
2015/01/13 PHP
Laravel 5.3 学习笔记之 安装
2016/08/28 PHP
php中照片旋转 (orientation) 问题的正确处理
2017/02/16 PHP
基于jQuery的弹出消息插件 DivAlert之旅(一)
2010/04/01 Javascript
JQuery制作的放大效果的popup对话框(未添加任何jquery plugin)分享
2013/04/28 Javascript
jquery中交替点击事件toggle方法的使用示例
2013/12/08 Javascript
关于jQuery判断元素是否存在的问题示例探讨
2014/07/21 Javascript
jQuery中element选择器用法实例
2014/12/29 Javascript
JavaScript实现函数返回多个值的方法
2015/06/09 Javascript
JS封装的选项卡TAB切换效果示例
2016/09/20 Javascript
JS实现购物车特效
2017/02/02 Javascript
JavaScript实现的XML与JSON互转功能详解
2017/02/16 Javascript
js实现GIF图片的分解和合成
2019/10/24 Javascript
Vue+Node实现的商城用户管理功能示例
2019/12/23 Javascript
[47:48]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第三局
2016/02/28 DOTA
浅析Python中的多重继承
2015/04/28 Python
Python制作爬虫抓取美女图
2016/01/20 Python
python发送邮件功能实现代码
2016/07/15 Python
python jieba分词并统计词频后输出结果到Excel和txt文档方法
2018/02/11 Python
python多进程实现文件下载传输功能
2018/07/28 Python
python将处理好的图像保存到指定目录下的方法
2019/01/10 Python
Python删除n行后的其他行方法
2019/01/28 Python
tensorflow使用freeze_graph.py将ckpt转为pb文件的方法
2020/04/22 Python
Python Django form 组件动态从数据库取choices数据实例
2020/05/19 Python
Python Request类源码实现方法及原理解析
2020/08/17 Python
解决Python3.7.0 SSL低版本导致Pip无法使用问题
2020/09/03 Python
python实现计算图形面积
2021/02/22 Python
测控技术与仪器个人求职信范文
2013/12/30 职场文书
《生命的药方》教学反思
2014/04/08 职场文书
《望庐山瀑布》教学反思
2014/04/22 职场文书
求职信内容怎么写
2014/05/26 职场文书
小学母亲节活动总结
2015/02/10 职场文书
新郎接新娘保证书
2015/05/08 职场文书
《叶问2》观后感
2015/06/15 职场文书
MySQL的InnoDB存储引擎的数据页结构详解
2022/03/03 MySQL