爬取博客园文章列表

爬取博客园文章列表,假设页面的URL是https://www.cnblogs.com/loaderman

要求:使用requests获取页面信息,用XPath / re 做数据提取 获取每个博客里的标题,描述,链接地址,日期等保存到 json 文件内

示例:

# -*- coding:utf-8 -*-

import urllib2import jsonfrom lxml import etree

url = "https://www.cnblogs.com/loaderman/"headers = {"User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}

request = urllib2.Request(url, headers=headers)

html = urllib2.urlopen(request).read()# 响应返回的是字符串,解析为HTML DOM模式 text = etree.HTML(html)

text = etree.HTML(html)# 返回所有结点位置,contains()模糊查询方法,第一个参数是要匹配的标签,第二个参数是标签名部分内容node_list = text.xpath('//div[contains(@class, "post")]')print (node_list)items = {}for each in node_list:    print (each)    title = each.xpath(".//h2/a[@class='postTitle2']/text()")[0]    detailUrl = each.xpath(".//a[@class='postTitle2']/@href")[0]    content = each.xpath(".//div[@class='c_b_p_desc']/text()")[0]    date = each.xpath(".//p[@class='postfoot']/text()")[0]

    items = {        "title": title,        "image": detailUrl,        "content": content,        "date": date,

    }

    with open("loaderman.json", "a") as f:        f.write(json.dumps(items, ensure_ascii=False).encode("utf-8") + "\n")

效果:

多线程爬虫案例

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

python下多线程的思考

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

  • 初始化:class Queue.Queue(maxsize) FIFO 先进先出

  • 包中的常用方法:

    Queue.qsize() 返回队列的大小

    Queue.empty() 如果队列为空,返回True,反之False

    Queue.full() 如果队列满了,返回True,反之False

    Queue.full 与 maxsize 大小对应

    Queue.get([block[, timeout]])获取队列,timeout等待时间

  • 创建一个“队列”对象

    import Queue

    myqueue = Queue.Queue(maxsize = 10)

  • 将一个值放入队列中

    myqueue.put(10)

  • 将一个值从队列中取出

    myqueue.get()

示意图:

# -*- coding:utf-8 -*-

# 使用了线程库import threading# 队列from Queue import Queue# 解析库from lxml import etree# 请求处理import requests# json处理import jsonimport time

class ThreadCrawl(threading.Thread):    def __init__(self, threadName, pageQueue, dataQueue):        # threading.Thread.__init__(self)        # 调用父类初始化方法        super(ThreadCrawl, self).__init__()        # 线程名        self.threadName = threadName        # 页码队列        self.pageQueue = pageQueue        # 数据队列        self.dataQueue = dataQueue        # 请求报头        self.headers = {"User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}

    def run(self):        print "启动 " + self.threadName        while not CRAWL_EXIT:            try:                # 取出一个数字,先进先出                # 可选参数block,默认值为True                # 1. 如果对列为空,block为True的话,不会结束,会进入阻塞状态,直到队列有新的数据                # 2. 如果队列为空,block为False的话,就弹出一个Queue.empty()异常,                page = self.pageQueue.get(False)                url = "https://www.cnblogs.com/loaderman/default.html?page=" + str(page)                # print url                content = requests.get(url, headers=self.headers).text                time.sleep(1)                self.dataQueue.put(content)                # print len(content)            except:                pass        print "结束 " + self.threadName

class ThreadParse(threading.Thread):    def __init__(self, threadName, dataQueue, filename, lock):        super(ThreadParse, self).__init__()        # 线程名        self.threadName = threadName        # 数据队列        self.dataQueue = dataQueue        # 保存解析后数据的文件名        self.filename = filename        # 锁        self.lock = lock

    def run(self):        print "启动" + self.threadName        while not PARSE_EXIT:            try:                html = self.dataQueue.get(False)                self.parse(html)            except:                pass        print "退出" + self.threadName

    def parse(self, html):        # 解析为HTML DOM        html = etree.HTML(html)

        node_list = html.xpath('//div[contains(@class, "post")]')        print (node_list)        items = {}        for each in node_list:            print (each)            title = each.xpath(".//h2/a[@class='postTitle2']/text()")[0]            detailUrl = each.xpath(".//a[@class='postTitle2']/@href")[0]            content = each.xpath(".//div[@class='c_b_p_desc']/text()")[0]            date = each.xpath(".//p[@class='postfoot']/text()")[0]

            items = {                "title": title,                "image": detailUrl,                "content": content,                "date": date,

            }

            with open("loadermanThread.json", "a") as f:                f.write(json.dumps(items, ensure_ascii=False).encode("utf-8") + "\n")

CRAWL_EXIT = FalsePARSE_EXIT = False

def main():    # 页码的队列,表示20个页面    pageQueue = Queue(20)    # 放入1~10的数字,先进先出    for i in range(1, 21):        pageQueue.put(i)

    # 采集结果(每页的HTML源码)的数据队列,参数为空表示不限制    dataQueue = Queue()

    filename = open("duanzi.json", "a")    # 创建锁    lock = threading.Lock()

    # 三个采集线程的名字    crawlList = ["采集线程1号", "采集线程2号", "采集线程3号"]    # 存储三个采集线程的列表集合    threadcrawl = []    for threadName in crawlList:        thread = ThreadCrawl(threadName, pageQueue, dataQueue)        thread.start()        threadcrawl.append(thread)

    # 三个解析线程的名字    parseList = ["解析线程1号", "解析线程2号", "解析线程3号"]    # 存储三个解析线程    threadparse = []    for threadName in parseList:        thread = ThreadParse(threadName, dataQueue, filename, lock)        thread.start()        threadparse.append(thread)

    # 等待pageQueue队列为空,也就是等待之前的操作执行完毕    while not pageQueue.empty():        pass

    # 如果pageQueue为空,采集线程退出循环    global CRAWL_EXIT    CRAWL_EXIT = True

    print "pageQueue为空"

    for thread in threadcrawl:        thread.join()        print "1"

    while not dataQueue.empty():        pass

    global PARSE_EXIT    PARSE_EXIT = True

    for thread in threadparse:        thread.join()        print "2"

    with lock:        # 关闭文件        filename.close()    print "谢谢使用!"

if __name__ == "__main__":    main()

效果:

码上加油站

一起来加油

长按扫码关注

记得点个在看哦!

python queue查询空_【Python】多线程爬虫案例相关推荐

  1. python实现一个很简单的多线程爬虫

    需求 无聊用python写一个爬虫爬取某个视频网站的内容,获取名称地址时长和更新时间保存到数据库头,以前没用过也没学多线程所以接直接顺着来,按照python的简洁性几行代码就搞定,一刷下来没问题,保存 ...

  2. python多线程爬虫案例之爬取麦田

    import threading import requests from time import sleep from bs4 import BeautifulSoup import csv fro ...

  3. python课表查询系统_使用python抓取广西科技大学教务系统课程表

    因学校教务系统课程表查询功能累赘,服务器经常挂,同时也不适合手机端查询,所以用python开发爬虫抓取所有课程表,放到我的服务器上面. 本文仅供学习. 特性 中途退出程序再次运行不会抓取到重复课程表 ...

  4. python多进程编程实例_[python] Python多进程编程技术实例分析

    这篇文章主要介绍了Python多进程编程技术,包括了线程.队列.同步等概念及相关的技巧总结,需要的朋友可以参考下 本文以实例形式分析了Python多进程编程技术,有助于进一步Python程序设计技巧. ...

  5. python查看excel编码格式_[Python]实现处理读写xlsx xls excel文件格式(含中文处理方法)...

    最近有个需求要处理excel 格式的数据,数据量比较大.用传统的语言似乎不太好处理,于是改用python实现,这里记录一下实现过程. 首先,科普一下xlsx xls的excel文件区别是什么. xls ...

  6. python朋友圈刷屏_“Python太火了!请救救Java!”9万程序员刷屏朋友圈 !

    没想到有生之年,笔者能观察到"霸主陨落"的过程,继PLPY4月榜单官宣,Python躺赢,再度"夺"冠,实力甩下Java和C后,近期,Stack Overflo ...

  7. python 打包 小文件_[Python][小知识][NO.5] 使用 Pyinstaller 打包成.exe文件

    1.安装 pyinstaller 插件 cmd命令:pip install PyInstaller PS . o.o 不知道 easy_install 的百度吧. 2.pyinstaller 简介 他 ...

  8. python shell如何打开_“python shell怎么打开“python shell启动教程

    python shell怎么打开 1.简介:如何在python中运行shell(bash命令) 2.工具/原料:python库:os.py 3.方法:import os command = 'date ...

  9. python输出文本居中_#python PIL ImageDraw text 文本居中#

    python pip pil有什么东西 你所问的问题实是属1.先参考[教程]Python中的内置的和方的模块搞懂PIL是属于第三方Python模块2.再参考:[待完善][总结]Python安装第三方的 ...

最新文章

  1. Web项目使用nginx实现代理端口访问,看这篇就够了
  2. 大数据学习笔记二:Ubuntu/Debian 下安装大数据框架Hadoop
  3. 2014家电盘点:求变与创新
  4. 提高显微镜分辨率方法_超分辨显微镜研究获进展
  5. Michael A. Cusumano
  6. what to do to make a phone call at dorm?
  7. php实现商品购物车添加功能,PHP实现添加购物车功能
  8. linux耳机检测,Audio Jack 的耳机检测和按键检测
  9. html%3ca%3e标签,How do I encode “” in a URL in an HTML attribute value?
  10. 【java笔记】File类(3):FileFilter文件过滤器原理和使用
  11. Tiny4412 小试牛刀
  12. 2020年西南交通大学数据仓库与数据挖掘期末考试题
  13. BZOJ2565最长双回文串——manacher
  14. 程序员刷简历领导看见很寒心,网友:找工作也要经过你同意?
  15. [敏捷开发培训] 燃尽图(Burndown Chart)
  16. 将https安全证书导入jdk中
  17. Spark:图(Graph)
  18. visibility的用法
  19. 19.3 Table 1-2.S3C2440A 289-Pin FBGA Pin Assignments (Sheet 4 of 9) (Continued)
  20. 某度网盘不限速下载,这里有个新方法~

热门文章

  1. MySQL:日期函数、时间函数总结
  2. springboot 使用 minio
  3. python代码html显示数据_通过AJAX success方法以html格式显示数据
  4. mysql事务和非事物_mysql事务型与非事务型表1.8.5.3. 事务和原子操作
  5. java if两个条件_java(3) if结构
  6. 城市运行一网统管_全国率先!“一屏观天下、一网管全城”,临港城市运行“一网统管”平台启动建设...
  7. 排序算法 —— 堆排序
  8. 哈希表的大小为何最好是素数
  9. rabbitmq+topic+java_译:5.RabbitMQ Java Client 之 Topics (主题)
  10. PHP定时抽奖怎么实现的,PHP 实现抽奖逻辑