设为首页 加入收藏

TOP

爬虫——多线程糗事百科案例(一)
2017-09-30 17:54:11 】 浏览:8391
Tags:爬虫 线程 百科 案例

案例:多线程爬虫

目标:爬取糗事百科段子,待爬取页面URL:http://www.qiushibaike.com/8hr/page/1

要求:

  1. 使用requests获取页面信息,用XPATH/re 做数据提取
  2. 获取每个帖子里的 用户头像链接、用户主页、用户名、用户性别、用户年龄、段子内容、点赞次数、评论次数
  3. 保存到本地json文件内
  4. 采用多线程

queue(队列对象)

queue是python中的标准库,可以直接import queue引用,队列是线程间最常用的交换数据的形式

python下多线程:

对于资源,加锁是个重要的环节。因为python原生的list, dict等,都是not thread safe的。而queue,是thread safe(线程案例)的,因此在满足使用条件下,建议使用队列

  1. 初始化:class queue.Queue(maxsize) FIFO(先进先出)
  2. 常用方法:
    1. queue.Queue.qsize() 返回队列的大小
    2. queue.Queue.empty() 如果队列为空,返回True,反之返回False
    3. queue.Queue.full() 如果队列满了,返回True,反之返回False
    4. queue.Queue.get([block[, timeout]]) 从队列中取出一个值,timeout为等待时间
  3. 创建一个“队列”对象
    • import queue
    • myqueue = queue.Queue(maxsize = 10)
  4. 将一个值放入队列中
    • myqueue.put(10)
  5. 将一个值从队列中取出
    • myqueue.get()
#!/usr/bin/python3
# -*- coding:utf-8 -*-
__author__ = 'mayi'

"""
案例:多线程爬虫
目标:爬取糗事百科段子,待爬取页面首页URL:http://www.qiushibaike.com/8hr/page/1
要求:
    1.使用requests获取页面信息,用XPATH/re 做数据提取
    2.获取每个帖子里的 用户头像链接、用户主页、用户名、用户性别、用户年龄、段子内容、点赞次数、评论次数
    3.保存到json文件内
    4.采用多线程
"""

import requests
from lxml import etree
from queue import Queue
import threading
import time
import json

# 数据队列
data_queue = Queue()
exitFlag_Parser = False
# 锁
lock = threading.Lock()

class ThreadCrawl(threading.Thread):
    """
    爬取线程类
    """
    def __init__(self, thread_name, page_queue):
        threading.Thread.__init__(self)
        self.thread_name = thread_name
        self.page_queue = page_queue
        self.url = "http://www.qiushibaike.com/8hr/page/"
        self.header = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36'}

    def run(self):
        print(self.thread_name + " Starting...")
        self.qiushi_spider()
        print(self.thread_name + " Exiting...")

    def qiushi_spider(self):
        global data_queue
        while True:
            # page队列为空时,循环结束
            if self.page_queue.empty():
                break
            else:
                page = self.page_queue.get()
                full_url = self.url + str(page) + "/"
                print(full_url)

            # 多次尝试发送请求失败后结束、防止死循环
            timeout = 5
            while timeout:
                try:
                    # 防止访问太快
                    time.sleep(1)
                    content = requests.get(full_url, headers = self.header)
                    data_queue.put(content.text)
                    break
                except Exception as e:
                    print(e)
                    timeout -= 1
                    time.sleep(1)


class ThreadParser(threading.Thread):
    """
    页面解析类
    """
    def __init__(self, thread_name, file_name):
        threading.Thread.__init__(self)
        self.thread_name = thread_name
        self.file_name = file_name

    def run(self):
        # 开始
        print(self.thread_name + " Starting...")
        global data_queue, exitFlag_Parser
        while not exitFlag_Parser:
            try:
                item = data_queue.get(block = False)
                if item:
                    self.parse_data(item)
                    data_queue.task_done()
            except:
                pass
        # 结束
        print(self.thread_name + " Exiting...")

    def parse_data(self, item):
        """
        解析网页函数
        :param item: 网页内容
        """
        global lock
        try:
            html = etree.HTML(item)
            # id = qiushi_tag_119336220:id均包含:qiushi_tag_
            result = html.xpath('//div[contains(@id,"qiushi_tag_")]')
            for res in result:
                try:
                    # 用户头像链接、用户主页、用户名、用户性别、用户年龄、段子内容、点赞次数、评论次数
                    # 用户头像链接
                    head_url = res.xpath('.//img/@src')[0]
                    # 用户主页
                    home_url = "http://www.qiushibaike.com" + res.xpath('.//a/@href')[0]
                    # 用户名
                    user_name = res.xpath(
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Python装饰器与面向切面编程 下一篇python数据结构之链表

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目