• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell
您的位置:首页 > 脚本语言 >python > python实现爬虫统计学校BBS男女比例之多线程爬虫(二)

python实现爬虫统计学校BBS男女比例之多线程爬虫(二)

作者:lijiao 字体:[增加 减小] 来源:互联网

lijiao 通过本文主要向大家介绍了python多线程爬虫,python3多线程爬虫,python爬虫工程师,python爬虫课程,python爬虫源码等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

接着第一篇继续学习。

一、数据分类

正确数据:id、性别、活动时间三者都有

放在这个文件里file1 = 'ruisi\\correct%s-%s.txt' % (startNum, endNum)

数据格式为293001 男 2015-5-1 19:17

  • 没有时间:有id、有性别,无活动时间

放这个文件里file2 = 'ruisi\\errTime%s-%s.txt' % (startNum, endNum)

数据格式为2566 女 notime

  • 用户不存在:该id没有对应的用户

放这个文件里file3 = 'ruisi\\notexist%s-%s.txt' % (startNum, endNum)

数据格式为29005 notexist

  • 未知性别:有id,但是性别从网页上无法得知(经检查,这种情况也没有活动时间)

放这个文件里 file4 = 'ruisi\\unkownsex%s-%s.txt' % (startNum, endNum)

数据格式 221794 unkownsex

  • 网络错误:网断了,或者服务器故障,需要对这些id重新检查

放这个文件里 file5 = 'ruisi\\httperror%s-%s.txt' % (startNum, endNum)

数据格式 271004 httperror

如何不间断得爬虫信息

  • 本项目有一个考虑:是不间断爬取信息,如果因为断网、BBS服务器故障啥的,我的爬虫程序就退出的话。那我们还得从间断的地方继续爬,或者更麻烦的是从头开始爬。
  • 所以,我采取的方法是,如果遇到故障,就把这些异常的id记录下来。等一次遍历之后,才对这些异常的id进行重新爬取性别。
  • 本文系列(一)给出了一个 getInfo(myurl, seWord),通过给定链接和给定正则表达式爬取信息。
  • 这个函数可以用来查看性别的最后活动时间信息。
  • 我们再定义一个安全的爬取函数,不会间断程序运行的,这儿用到try except异常处理。

这儿代码试了两次getInfo(myurl, seWord),如果第2次还是抛出异常了,就把这个id保存在file5里面
如果能获取到信息,就返回信息

file5 = 'ruisi\\httperror%s-%s.txt' % (startNum, endNum)
def safeGet(myid, myurl, seWord):
  try:
    return getInfo(myurl, seWord)
  except:
    try:
      return getInfo(myurl, seWord)
    except:
      httperrorfile = open(file5, 'a')
      info = '%d %s\n' % (myid, 'httperror')
      httperrorfile.write(info)
      httperrorfile.close()
      return 'httperror'
</div>

依次遍历,获取id从[1,300,000]的用户信息

我们定义一个函数,这儿的思路是获取sex和time,如果有sex,进而继续判断是否有time;如果没sex,判断是否这个用户不存在还是性别无法爬取。

其中要考虑到断网或者BBS服务器故障的情况。

url1 = 'http://rs.xidian.edu.cn/home.php?mod=space&uid=%s'
url2 = 'http://rs.xidian.edu.cn/home.php?mod=space&uid=%s&do=profile'
def searchWeb(idArr):
  for id in idArr:
    sexUrl = url1 % (id) #将%s替换为id
    timeUrl = url2 % (id)
    sex = safeGet(id,sexUrl, sexRe)
    if not sex: #如果sexUrl里面找不到性别,在timeUrl再尝试找一下
      sex = safeGet(id,timeUrl, sexRe)
    time = safeGet(id,timeUrl, timeRe)

    #如果出现了httperror,需要重新爬取
    if (sex is 'httperror') or (time is 'httperror') :
      pass
    else:
      if sex:
        info = '%d %s' % (id, sex)
        if time:
          info = '%s %s\n' % (info, time)
          wfile = open(file1, 'a')
          wfile.write(info)
          wfile.close()
        else:
          info = '%s %s\n' % (info, 'notime')
          errtimefile = open(file2, 'a')
          errtimefile.write(info)
          errtimefile.close()
      else:
        #这儿是性别是None,然后确定一下是不是用户不存在
        #断网的时候加上这个,会导致4个重复httperror
        #可能用户的性别我们无法知道,他没有填写
        notexist = safeGet(id,sexUrl, notexistRe)
        if notexist is 'httperror':
          pass
        else:
          if notexist:
            notexistfile = open(file3, 'a')
            info = '%d %s\n' % (id, 'notexist')
            notexistfile.write(info)
            notexistfile.close()
          else:
            unkownsexfile = open(file4, 'a')
            info = '%d %s\n' % (id, 'unkownsex')
            unkownsexfile.write(info)
            unkownsexfile.close()

</div>

这儿后期检查发现了一个问题

 sex = safeGet(id,sexUrl, sexRe)
 if not sex:
   sex = safeGet(id,timeUrl, sexRe)
 time = safeGet(id,timeUrl, timeRe)
</div>

这个代码如果断网的时候,调用了3次safeGet,每次调用都会往文本里面同一个id写多次httperror

251538 httperror
251538 httperror
251538 httperror
251538 httperror
</div>

多线程爬取信息?

数据统计可以用多线程,因为是独立的多个文本
1、Popen介绍

使用Popen可以自定义标准输入、标准输出和标准错误输出。我在SAP实习的时候,项目组在linux平台下经常使用Popen,可能是因为可以方便重定向输出。

下面这段代码借鉴了以前项目组的实现方法,Popen可以调用系统cmd命令。下面3个communicate()连在一起表示要等这3个线程都结束。

疑惑?
试验了一下,必须3个communicate()紧挨着才能保证3个线程同时开启,最后等待3个线程都结束。

p1=Popen(['python', 'ruisi.py', str(s0),str(s1)],bufsize=10000, stdout=subprocess.PIPE)

p2=Popen(['python', 'ruisi.py', str(s1),str(s2)],bufsize=10000, stdout=subprocess.PIPE)

p3=Popen(['python', 'ruisi.py', str(s2),str(s3)],bufsize=10000, stdout=subprocess.PIPE)

p1.communicate()
p2.communicate()
p3.communicate()

</div>

2、定义一个单线程的爬虫

用法:python ruisi.py <startNum> <endNum>

这段代码就是爬取[startNum, endNum)信息,输出到相应的文本里。它是一个单线程的程序,若要实现多线程的话,在外部调用它的地方实现多线程。

# ruisi.py
# coding=utf-8
import urllib2, re, sys, threading, time,thread

# myurl as 指定链接
# seWord as 正则表达式,用unicode表示
# 返回根据正则表达式匹配的信息或者None
def getInfo(myurl, seWord):
  headers = {
    'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'
  }
  req = urllib2.Request(
    url=myurl,
    headers=headers
  )
  time.sleep(0.3)
  response = urllib2.urlopen(req)
  html = response.read()
  html = unicode(html, 'utf-8')
  timeMatch = seWord.search(html)
  if timeMatch:
    s = timeMatch.groups()
    return s[0]
  else:
    return None

#尝试两次getInfo()
#第2次失败后,就把这个id标记为httperror
def safeGet(myid, myurl, seWord):
  try:
    return getInfo(myurl, seWord)
  except:
    try:
      return getInfo(myurl, seWord)
    except:
      httperrorfile = open(file5, 'a')
      info = '%d %s\n' % (myid, 'httperror')
      httperrorfile.write(info)
      httperrorfile.close()
      return 'httperror'


#输出一个 idArr 范围,比如[1,1001)
def searchWeb(idArr):
  for id in idArr:
    sexUrl = url1 % (id)
    timeUrl = url2 % (id)
    sex = safeGet(id,sexUrl, sexRe)
    if not sex:
      sex = safeGet(id,timeUrl, sexRe)
    time = safeGet(id,timeUrl, timeRe)

    if (sex is 'httperror') or (time is 'httperror') :
      pass
    else:
      if sex:
        info = '%d %s' % (id, sex)
        if time:
          info = '%s %s\n' % (info, time)
          wfile = open(file1, 'a')
          wfile.write(info)
          wfile.close()
        else:
          info = '%s %s\n' % (info, '
  


 

您可能想查找下面的文章:

  • Python多线程实现同步的四种方式
  • Python多线程实现同步的四种方式
  • python实现多线程抓取知乎用户
  • Python中多线程的创建及基本调用方法
  • Python中多线程的创建及基本调用方法
  • 深入解析Python中的线程同步方法
  • 深入解析Python中的线程同步方法
  • python实现多线程的两种方式
  • Python多线程爬虫简单示例
  • Python多线程、异步+多进程爬虫实现代码

相关文章

  • Django的数据模型访问多对多键值的方法
  • python操作mysql中文显示乱码的解决方法
  • python在多玩图片上下载妹子图的实现代码
  • python实现ipsec开权限实例
  • Python标准库之collections包的使用教程
  • Python利用operator模块实现对象的多级排序详解
  • 从零学Python之入门(五)缩进和选择
  • 怎样使用Python脚本日志功能
  • 实例讲解Python中global语句下全局变量的值的修改
  • python实现图片批量剪切示例

文章分类

  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell

最近更新的内容

    • python 合并文件的具体实例
    • Python的消息队列包SnakeMQ使用初探
    • 使用Python脚本将绝对url替换为相对url的教程
    • python实现超简单端口转发的方法
    • 编写简单的Python程序来判断文本的语种
    • 线程和进程的区别及Python代码实例
    • 理解Python中函数的参数
    • python中__call__方法示例分析
    • 浅谈Python类里的__init__方法函数,Python类的构造函数
    • Python安装第三方库及常见问题处理方法汇总

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有