python爬虫爬取幽默笑话网站


Posted in Python onOctober 24, 2019

爬取网站为:http://xiaohua.zol.com.cn/youmo/

查看网页机构,爬取笑话内容时存在如下问题:

1、每页需要进入“查看更多”链接下面网页进行进一步爬取内容每页查看更多链接内容比较多,多任务进行,这里采用线程池的方式,可以有效地控制系统中并发线程的数量。避免当系统中包含有大量的并发线程时,导致系统性能下降,甚至导致 Python 解释器崩溃,引入线程池,花费时间更少,更效率。

  • 创建线程 池threadpool.ThreadPool()
  • 创建需要线程池处理的任务即threadpool.makeRequests(),makeRequests存放的是要开启多线程的函数,以及函数相关参数和回调函数,其中回调函数可以不写(默认是无)。
  • 将创建的多个任务put到线程池中,threadpool.putRequest()
  • 等到所有任务处理完毕theadpool.pool()

2、查看链接笑话页内容,div元素内部文本分布比较混乱。有的分布在<p>链接内有的属于div的文本,可采用正则表达式的方式解决。

注意2种获取元素节点的方式:

1)lxml获取节点字符串

res=requests.get(url,headers=headers)
html = res.text
 
lxml 获取节点写法
element=etree.HTML(html)
divEle=element.xpath("//div[@class='article-text']")[0]  # 获取div节点
div= etree.tostring(divEle, encoding = 'utf-8' ).decode('utf-8') # 转换为div字符串

2)正则表达式写法1,过滤回车、制表符和p标签

# 第一种方式:replace
content = re.findall('<div class="article-text">(.*?)</div>',html,re.S)
content = content[0].replace('\r','').replace('\t','').replace('<p>','').replace('</p>','').strip()

3)正则表达式写法2,过滤回车、制表符和p标签

# 第二种方式:sub
for index in range(len(content)):
  content[index] = re.sub(r'(\r|\t|<p>|<\/p>)+','',content[index]).strip()
 
list = ''.join(content)
print(list)

3、完整代码

index.py

import requests
import threadpool
import time
import os,sys
import re
from lxml import etree
from lxml.html import tostring
 
 
class ScrapDemo():
  next_page_url=""  #下一页的URL
  page_num=1 #当前页
  detail_url_list=0 #详情页面URL地址list
  deepth=0 #设置抓取的深度
  headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36"
  }
  fileNum=0
 
  def __init__(self,url):
    self.scrapyIndex(url)
 
  def threadIndex(self,urllist): #开启线程池
    if len(urllist) == 0:
      print("请输入需要爬取的地址")
      return False
    ScrapDemo.detail_url_list=len(urllist)
    pool=threadpool.ThreadPool(len(urllist))
    requests=threadpool.makeRequests(self.detailScray,urllist)
    for req in requests:  
      pool.putRequest(req)
      time.sleep(0.5)
    pool.wait()
 
  def detailScray(self,url): # 获取html结构
    if not url == "":
      url='http://xiaohua.zol.com.cn/{}'.format(url)
      res=requests.get(url,headers=ScrapDemo.headers)
      html=res.text
      # element=etree.HTML(html)
      # divEle=element.xpath("//div[@class='article-text']")[0]  # Element div     
      self.downloadText(html) 
 
  def downloadText(self,ele): # 抓取数据并存为txt文件
    clist = re.findall('<div class="article-text">(.*?)</div>',ele,re.S)
    for index in range(len(clist)):
      '''
        正则表达式:过滤掉回车、制表符和p标签
      '''
      clist[index]=re.sub(r'(\r|\t|<p>|<\/p>)+','',clist[index]) 
    content="".join(clist)
    # print(content) 
    basedir=os.path.dirname(__file__)
    filePath=os.path.join(basedir)
    filename="xiaohua{0}-{1}.txt".format(ScrapDemo.deepth,str(ScrapDemo.fileNum))
    file=os.path.join(filePath,'file_txt',filename)
    try:
      f=open(file,"w")
      f.write(content)
      if ScrapDemo.fileNum == (ScrapDemo.detail_url_list - 1):
        print(ScrapDemo.next_page_url)
        print(ScrapDemo.deepth)
        if not ScrapDemo.next_page_url == "":
          self.scrapyIndex(ScrapDemo.next_page_url)
    except Exception as e:
      print("Error:%s" % str(e))
 
    ScrapDemo.fileNum=ScrapDemo.fileNum+1
    print(ScrapDemo.fileNum)
 
  def scrapyIndex(self,url): 
    if not url == "":
      ScrapDemo.fileNum=0
      ScrapDemo.deepth=ScrapDemo.deepth+1
      print("开启第{0}页抓取".format(ScrapDemo.page_num))
      res=requests.get(url,headers=ScrapDemo.headers)
      html=res.text
      element=etree.HTML(html)
      a_urllist=element.xpath("//a[@class='all-read']/@href") # 当前页所有查看全文
      next_page=element.xpath("//a[@class='page-next']/@href") # 获取下一页的url
      ScrapDemo.next_page_url='http://xiaohua.zol.com.cn/{}'.format(next_page[0])
      if not len(next_page) == 0 and ScrapDemo.next_page_url != url:
        ScrapDemo.page_num=ScrapDemo.page_num+1
        self.threadIndex(a_urllist[:]) 
      else:
        print('下载完成,当前页数为{}页'.format(ScrapDemo.page_num))
        sys.exit()

runscrapy.py

from app import ScrapDemo
url="http://xiaohua.zol.com.cn/youmo/"
ScrapDemo(url)

运行如下:

python爬虫爬取幽默笑话网站

总共1988个文件,下载完成。

python爬虫爬取幽默笑话网站

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

Python 相关文章推荐
深入讨论Python函数的参数的默认值所引发的问题的原因
Mar 30 Python
Python lxml模块安装教程
Jun 02 Python
以一个投票程序的实例来讲解Python的Django框架使用
Feb 18 Python
浅谈python 线程池threadpool之实现
Nov 17 Python
python3.6+opencv3.4实现鼠标交互查看图片像素
Feb 26 Python
Python Requests库基本用法示例
Aug 20 Python
python实现C4.5决策树算法
Aug 29 Python
三个python爬虫项目实例代码
Dec 28 Python
python 字典item与iteritems的区别详解
Apr 25 Python
Pygame的程序开始示例代码
May 07 Python
tensorflow 动态获取 BatchSzie 的大小实例
Jun 30 Python
matplotlib 画动态图以及plt.ion()和plt.ioff()的使用详解
Jan 05 Python
python栈的基本定义与使用方法示例【初始化、赋值、入栈、出栈等】
Oct 24 #Python
python 队列基本定义与使用方法【初始化、赋值、判断等】
Oct 24 #Python
python单向链表的基本实现与使用方法【定义、遍历、添加、删除、查找等】
Oct 24 #Python
Windows下PyCharm2018.3.2 安装教程(图文详解)
Oct 24 #Python
python实现获取单向链表倒数第k个结点的值示例
Oct 24 #Python
python模块导入的方法
Oct 24 #Python
python读取word 中指定位置的表格及表格数据
Oct 23 #Python
You might like
安健A254立体声随身听的分析与打磨
2021/03/02 无线电
PHP实现多服务器session共享之NFS共享的方法
2007/03/16 PHP
用PHP写的MySQL数据库用户认证系统代码
2007/03/22 PHP
深入理解require与require_once与include以及include_once的区别
2013/06/05 PHP
php写的AES加密解密类分享
2014/06/20 PHP
JS获取dom 对象 ajax操作 读写cookie函数
2009/11/18 Javascript
基于JQuery 的消息提示框效果代码
2011/07/31 Javascript
Jquery解析Json格式数据过程代码
2014/10/17 Javascript
JS实现判断滚动条滚到页面底部并执行事件的方法
2014/12/18 Javascript
JS仿iGoogle自定义首页模块拖拽特效的方法
2015/02/13 Javascript
JAVASCRIPT代码编写俄罗斯方块网页版
2015/11/26 Javascript
js将滚动条滚动到指定位置的简单实现方法
2016/06/25 Javascript
Bootstrap常用组件学习(整理)
2017/03/24 Javascript
vue2.0 和 animate.css的结合使用
2017/12/12 Javascript
浅析JS抽象工厂模式
2017/12/14 Javascript
vue watch自动检测数据变化实时渲染的方法
2018/01/16 Javascript
微信小程序switch组件使用详解
2018/01/31 Javascript
详解组件库的webpack构建速度优化
2018/06/18 Javascript
jQuery实现基本隐藏与显示效果的方法详解
2018/09/05 jQuery
Vue项目自动转换 px 为 rem的实现方法
2018/10/29 Javascript
vue项目中微信登录的实现操作
2020/09/08 Javascript
微信小程序入门之指南针
2020/10/22 Javascript
python列表与元组详解实例
2013/11/01 Python
详解Python中的相对导入和绝对导入
2017/01/06 Python
浅谈python socket函数中,send与sendall的区别与使用方法
2017/05/09 Python
浅谈numpy库的常用基本操作方法
2018/01/09 Python
python如何把嵌套列表转变成普通列表
2018/03/20 Python
Python实现对特定列表进行从小到大排序操作示例
2019/02/11 Python
Python实现一个优先级队列的方法
2020/07/31 Python
HTML5 在canvas中绘制文本附效果图
2014/06/23 HTML / CSS
顶岗实习计划书
2014/01/10 职场文书
办护照工作证明范本
2014/01/14 职场文书
成考报名单位证明范本
2014/01/16 职场文书
宾馆总经理岗位职责
2014/02/14 职场文书
2015最新婚礼主持词
2015/06/30 职场文书
使用Redis做预定库存缓存功能
2022/04/02 Redis