import requests
from lxml import etree
import json
import threading
import queue # 采集html类
class GetHtml(threading.Thread):
def __init__(self, page_queue):
threading.Thread.__init__(self)
self.page_queue = page_queue def run(self):
self.do_get_html() def do_get_html(self):
headers = {"User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0"}
global data_queue
while True:
if self.page_queue.empty():
break
page = self.page_queue.get()
url = "https://www.qiushibaike.com/8hr/page/%s/" % str(page)
timeout = 5
while timeout > 0:
try:
_response = requests.get(url, headers=headers)
html = _response.content
# 保存到待解析队列
data_queue.put(html)
break
except ConnectionError as e:
print(e)
timeout -= 1
if timeout < 0:
print("time out, url: " + url) class ParseHtml(threading.Thread):
def __init__(self):
threading.Thread.__init__(self) def run(self):
self.do_parse_data() def do_parse_data(self):
global total, f
while True:
if data_queue.empty():
break
try:
html = data_queue.get()
text = etree.HTML(html)
list_node = text.xpath("//li[contains(@id, 'qiushi_tag_')]")
for node in list_node:
username = node.xpath(".//a[@class='recmd-user']/img/@alt")[0]
user_img = node.xpath(".//a[@class='recmd-user']/img/@src")[0]
zan_num = node.xpath(".//div[@class='recmd-num']/span[position()=1]/text()")[0]
ping_num = node.xpath(".//div[@class='recmd-num']/span[position()=4]/text()")
content = node.xpath(".//a[@class='recmd-content']/text()")
if len(ping_num) > 0:
ping_num = ping_num[0]
else:
ping_num = 0
if len(content) > 0:
content = content[0]
else:
content = ""
result = {
"username": username,
"imgUrl": user_img,
"vote": zan_num,
"comments": ping_num,
"content": content
}
total += 1
f.write((json.dumps(result, ensure_ascii=False) + "\n").encode("utf-8"))
except RuntimeError as e:
print(e) def main():
# 将采集到的html保存到队列
for i in range(1, 21):
page_queue.put(i)
# 开启采集线程
get_html_thread = []
for i in range(100):
get_html = GetHtml(page_queue)
get_html.start()
get_html_thread.append(get_html)
# 等待所有采集线程完成
for thread in get_html_thread:
thread.join()
# 开启解析线程
parse_html_thread = []
for i in range(100):
parse_html = ParseHtml()
parse_html.start()
parse_html_thread.append(parse_html)
# 等待所有解析线程完成
for thread in parse_html_thread:
thread.join()
# 关闭文件
f.close()
print("采集数据完成,总共%s条数据" % total) if __name__ == '__main__':
data_queue = queue.Queue()
page_queue = queue.Queue()
f = open("./qunaerwang.json", "wb")
total = 0
main()

数据:

{"username": "夲少姓〖劉〗", "imgUrl": "//pic.qiushibaike.com/system/avtnew/1187/11878716/thumb/20190520091055.jpg?imageView2/1/w/50/h/50", "vote": "", "comments": "", "content": "马中赤兔人中啥了?"}
{"username": "一枕清霜゛", "imgUrl": "//pic.qiushibaike.com/system/avtnew/3371/33712263/thumb/20190511210156.jpg?imageView2/1/w/50/h/50", "vote": "", "comments": "", "content": "一个段子手,一个神回复"}
{"username": "窝里斗窝里", "imgUrl": "//pic.qiushibaike.com/system/avtnew/1427/14275616/thumb/20181228173532.jpg?imageView2/1/w/50/h/50", "vote": "", "comments": "", "content": "鹰科猛禽走路的姿势看上去总是屌屌的!!"}
{"username": "2丫头还是个宝宝", "imgUrl": "//pic.qiushibaike.com/system/avtnew/2219/22190863/thumb/20190131225946.jpg?imageView2/1/w/50/h/50", "vote": "", "comments": "", "content": "都说孩子玩沙子有助于孩子的智力发育,所以家里买了一车沙子放院子给逗逗玩。逗逗拿了一个铲子和一个望远镜玩具,当着我的面把望远镜在埋沙子里。拉着我的手:妈妈,我在沙"}
{"username": "★像风一样一样★", "imgUrl": "//pic.qiushibaike.com/system/avtnew/2716/27163432/thumb/20180306191622.JPEG?imageView2/1/w/50/h/50", "vote": "", "comments": "", "content": "去朋友家看到的,特殊的插排,一个插排才多少钱啊?"}
{"username": "无语滴滴", "imgUrl": "//pic.qiushibaike.com/system/avtnew/3782/37821797/thumb/20190430173233.jpg?imageView2/1/w/50/h/50", "vote": "", "comments": "", "content": "朋友和他女友吵架闹分手,我们都去劝。他女友抹抹眼泪看着窗外说了一句话:“要不是还有几个快递在路上,我真想死了算了。”"}
{"username": "愚人愚之不如愚己", "imgUrl": "//pic.qiushibaike.com/system/avtnew/1927/19270659/thumb/20160618154530.jpg?imageView2/1/w/50/h/50", "vote": "", "comments": "", "content": "老司机你发了多大的誓?"}
余下数据省略。。。

往后思路:

  1、保存到数据库

  2、保存到redis中、然后再同步到数据库

Python 之糗事百科多线程爬虫案例的更多相关文章

  1. python 爬糗事百科

    糗事百科网站段子爬取,糗事百科是我见过的最简单的网站了!!! #-*-coding:utf8-*- import requests import re import sys reload(sys) s ...

  2. (python)查看糗事百科文字 点赞 作者 等级 评论

    import requestsimport reheaders = { 'User-Agent':'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; ...

  3. [爬虫]用python的requests模块爬取糗事百科段子

    虽然Python的标准库中 urllib2 模块已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests 自称 “HTTP for Humans”,说明使用更 ...

  4. python scrapy实战糗事百科保存到json文件里

    编写qsbk_spider.py爬虫文件 # -*- coding: utf-8 -*- import scrapy from qsbk.items import QsbkItem from scra ...

  5. 爬虫_糗事百科(scrapy)

    糗事百科scrapy爬虫笔记 1.response是一个'scrapy.http.response.html.HtmlResponse'对象,可以执行xpath,css语法来提取数据 2.提取出来的数 ...

  6. Python爬虫(十八)_多线程糗事百科案例

    多线程糗事百科案例 案例要求参考上一个糗事百科单进程案例:http://www.cnblogs.com/miqi1992/p/8081929.html Queue(队列对象) Queue是python ...

  7. python 多线程糗事百科案例

    案例要求参考上一个糗事百科单进程案例 Queue(队列对象) Queue是python中的标准库,可以直接import Queue引用;队列是线程间最常用的交换数据的形式 python下多线程的思考 ...

  8. 【Python爬虫实战】多线程爬虫---糗事百科段子爬取

    多线程爬虫:即程序中的某些程序段并行执行,合理地设置多线程,可以让爬虫效率更高糗事百科段子普通爬虫和多线程爬虫分析该网址链接得出:https://www.qiushibaike.com/8hr/pag ...

  9. Python爬虫(十七)_糗事百科案例

    糗事百科实例 爬取糗事百科段子,假设页面的URL是: http://www.qiushibaike.com/8hr/page/1 要求: 使用requests获取页面信息,用XPath/re做数据提取 ...

随机推荐

  1. Android 自己定义控件实现刮刮卡效果 真的就仅仅是刮刮卡么

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40162163 , 本文出自:[张鸿洋的博客] 非常久以前也过一个html5的刮刮 ...

  2. JS执行环境栈及事件循环机制—简洁明了的讲解

    JavaScript解释器在浏览器中是单线程的,这意味着浏览器在同一时间内只执行一个事件,对于其他的事件我们把它们排队在一个称为 执行栈(调用栈) 的地方.下表是一个单线程栈的抽象视图: 我们已经知道 ...

  3. MongoDB集群——副本集

    1. 副本集的结构及原理 副本集包括三种节点:主节点.从节点.仲裁节点.主节点负责处理客户端请求,读.写数据, 记录在其上所有操作的oplog: 从节点定期轮询主节点获取这些操作,然后对自己的数据副本 ...

  4. 2015南阳CCPC H - Sudoku 数独

    H - Sudoku Description Yi Sima was one of the best counselors of Cao Cao. He likes to play a funny g ...

  5. elasticsearch 布尔过滤器 游标查询 Scroll

    组合过滤器 | Elasticsearch: 权威指南 | Elastic https://www.elastic.co/guide/cn/elasticsearch/guide/current/co ...

  6. oc83--自定义类实现copy方法

    // // main.m // 自定义类实现copy #import <Foundation/Foundation.h> #import "Person.h" #imp ...

  7. poj 2104 K-th Number 主席树+超级详细解释

    poj 2104 K-th Number 主席树+超级详细解释 传送门:K-th Number 题目大意:给出一段数列,让你求[L,R]区间内第几大的数字! 在这里先介绍一下主席树! 如果想了解什么是 ...

  8. 预编译头文件pch

    1.         预编译头文件 作用:提高编译效率.预编译头文件(扩展名为.PCH),是为了提高编译效率而使用的一种方法,把一个工程中较稳定的代码预先编译好放在一个文件(.PCH)里.避免每次编译 ...

  9. NodeJs函数式编程

    虽然标题是NodeJS函数式编程,但实际上NodeJS 是一个框架,不是一种语言,其采用的语言是 JavaScript.而JavaScript是一种典型的多范式编程语言,算不上是函数式语言,但它有函数 ...

  10. bzoj2194

    http://www.lydsy.com/JudgeOnline/problem.php?id=2194 卷积... 卷积并不高深,其实卷积就是两个多项式相乘的系数,但是得满足一点条件,就是f[n]= ...