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字典序问题实例
Sep 26 Python
python中pygame针对游戏窗口的显示方法实例分析(附源码)
Nov 11 Python
python 与GO中操作slice,list的方式实例代码
Mar 20 Python
python数据结构之列表和元组的详解
Sep 23 Python
详解Python异常处理中的Finally else的功能
Dec 29 Python
python发送告警邮件脚本
Sep 17 Python
Python对切片命名的实现方法
Oct 16 Python
python同时遍历数组的索引和值的实例
Nov 15 Python
对python 判断数字是否小于0的方法详解
Jan 26 Python
感知器基础原理及python实现过程详解
Sep 30 Python
PyQt5高级界面控件之QTableWidget的具体使用方法
Feb 23 Python
python 爬虫基本使用——统计杭电oj题目正确率并排序
Oct 26 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
mysql+php分页类(已测)
2008/03/31 PHP
PHP删除HTMl标签的三种解决方法
2013/06/30 PHP
php实现搜索一维数组元素并删除二维数组对应元素的方法
2015/07/06 PHP
PHP通过调用新浪API生成t.cn格式短网址链接的方法详解
2019/02/20 PHP
laravel 使用事件系统统计浏览量的实现
2019/10/16 PHP
HTML5之lang属性与dir属性的详解
2013/06/19 Javascript
用Jquery.load载入页面后样式没了页面混乱的解决方法
2014/10/20 Javascript
jQuery选择器源码解读(四):tokenize方法的Expr.preFilter
2015/03/31 Javascript
比例尺、缩略图、平移缩放之百度地图添加控件方法
2015/08/03 Javascript
Javascript基础_简单比较undefined和null 值
2016/06/14 Javascript
jQuery将表单序列化成一个Object对象的实例
2016/11/29 Javascript
将鼠标焦点定位到文本框最后(代码分享)
2017/01/11 Javascript
一篇文章搞定JavaScript类型转换(面试常见)
2017/01/21 Javascript
mpvue构建小程序的方法(步骤+地址)
2018/05/22 Javascript
页面点击小红心js实现代码
2018/05/26 Javascript
全面分析JavaScript 继承
2019/05/30 Javascript
[01:19:35]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#2Fnatic VS OG第二局
2016/03/05 DOTA
python查询sqlite数据表的方法
2015/05/08 Python
Python面向对象程序设计之继承与多继承用法分析
2018/07/13 Python
Tornado Web Server框架编写简易Python服务器
2018/07/28 Python
python爬虫超时的处理的实例
2018/12/19 Python
python使用requests.session模拟登录
2019/08/09 Python
Python龙贝格法求积分实例
2020/02/29 Python
Python命令行参数argv和argparse该如何使用
2021/02/08 Python
详解Python中openpyxl模块基本用法
2021/02/23 Python
澳大利亚优质葡萄酒专家:Vintage Cellars
2019/01/08 全球购物
Ellesse英国官网:意大利高级运动品牌
2019/07/23 全球购物
家长给小学生的评语
2014/01/30 职场文书
期末自我鉴定
2014/02/02 职场文书
党员2014两会学习心得体会
2014/03/17 职场文书
售后客服个人自我评价
2014/09/14 职场文书
公司酒会致辞
2015/07/30 职场文书
创业计划书之淘宝网店
2019/10/08 职场文书
MongoDB日志切割的三种方式总结
2021/09/15 MongoDB
关于ObjectUtils.isEmpty() 和 null 的区别
2022/02/28 Java/Android
Docker安装MySql8并远程访问的实现
2022/07/07 Servers