问题
# coding: utf-8
import requests
from pyquery import PyQuery
import threading
import queue
class Douyu(threading.Thread):
def __init__(self, directory_queue, thread_name):
self.thread_name = thread_name
self.directory_queue = directory_queue
self.rooms_queue = queue.Queue()
self.lock = threading.Lock()
threading.Thread.__init__(self)
def run(self):
self.get_rooms()
self.lock.acquire()
self.save_data()
self.lock.release()
def get_rooms(self):
while not self.directory_queue.empty():
directory_info = self.directory_queue.get_nowait()
html = requests.get(directory_info['url']).text
pq = PyQuery(html)
size = pq.find('#live-list-contentbox > li').size()
for index in range(size):
item = pq.find('#live-list-contentbox > li').eq(index)
title = item.find('a').attr('title')
url = 'http://www.douyu.com' + item.find('a').attr('href')
streamer = item.find('.dy-name').text()
directory = directory_info['name']
viewers = item.find('.dy-num').text()
self.rooms_queue.put({
'title': title,
'url': url,
'streamer': streamer,
'directory': directory,
'viewers': viewers
})
print('[%s] 获得房间: %s' %(self.thread_name, url))
def save_data(self):
while self.rooms_queue.not_empty:
room_info = self.rooms_queue.get()
content = '房间标题 => %s\n 主播名称 => %s\n 观众数量 => %s\n 分类栏目 => %s\n 房间链接 => %s\n\n' \
% (room_info['title'], room_info['streamer'], room_info['viewers'], room_info['directory'], room_info['url'])
with open('result.txt', 'a', encoding='utf-8') as f:
f.write(content)
print('[%s] 存储房间: %s' %(self.thread_name, room_info['url']))
def get_director():
directory_queue = queue.Queue()
html = requests.get('http://www.douyu.com/directory').text
pq = PyQuery(html)
size = pq.find('.unit').size()
for index in range(size):
item = pq.find('.unit').eq(index)
name = item.find('p').text()
url = item.find('a').attr('href')
img = item.find('img').attr('data-original')
directory_queue.put({
'name': name,
'url': 'http://www.douyu.com' + url,
'img': img
})
return directory_queue
if __name__ == '__main__':
thread_num = 20
threads = []
directory_queue = get_director()
for t in range(thread_num):
douyu = Douyu(directory_queue, '线程%s' %str(t+1))
print('[线程%s] 开启线程' %str(t+1))
douyu.setDaemon(True)
douyu.start()
threads.append(douyu)
for t in threads:
t.join()
LOG(分别截取了开始、中间和最后的 LOG):
[线程 1] 获得房间: http://www.douyu.com/889024
[线程 1] 获得房间: http://www.douyu.com/1397153
[线程 1] 获得房间: http://www.douyu.com/110441
[线程 1] 获得房间: http://www.douyu.com/134000
[线程 1] 获得房间: http://www.douyu.com/854503
[线程 3] 获得房间: http://www.douyu.com/220185
[线程 1] 获得房间: http://www.douyu.com/796666
[线程 1] 获得房间: http://www.douyu.com/1495611
[线程 3] 获得房间: http://www.douyu.com/312410
[线程 1] 获得房间: http://www.douyu.com/1061949
[线程 3] 获得房间: http://www.douyu.com/281276
[线程 6] 获得房间: http://www.douyu.com/659980
[线程 1] 获得房间: http://www.douyu.com/142823
[线程 3] 获得房间: http://www.douyu.com/127810
[线程 6] 获得房间: http://www.douyu.com/82961
[线程 3] 获得房间: http://www.douyu.com/lslalala
[线程 6] 获得房间: http://www.douyu.com/yiyi0409
[线程 1] 获得房间: http://www.douyu.com/860272
[线程 3] 获得房间: http://www.douyu.com/85513
[线程 6] 获得房间: http://www.douyu.com/222679
[线程 1] 获得房间: http://www.douyu.com/529719
[线程 1] 获得房间: http://www.douyu.com/1076249
[线程 3] 获得房间: http://www.douyu.com/yilingshu
[线程 6] 获得房间: http://www.douyu.com/548317
--------------------------------------------
[线程 1] 存储房间: http://www.douyu.com/668493
[线程 8] 存储房间: http://www.douyu.com/1687725
[线程 7] 存储房间: http://www.douyu.com/yueguanggugu
[线程 9] 存储房间: http://www.douyu.com/1756041
[线程 1] 存储房间: http://www.douyu.com/1055977
[线程 8] 存储房间: http://www.douyu.com/1728922
[线程 9] 存储房间: http://www.douyu.com/1646520
[线程 7] 存储房间: http://www.douyu.com/1658595
[线程 1] 存储房间: http://www.douyu.com/1298062
[线程 19] 获得房间: http://www.douyu.com/1380833
[线程 5] 获得房间: http://www.douyu.com/1001504
[线程 7] 存储房间: http://www.douyu.com/1480669
[线程 9] 存储房间: http://www.douyu.com/zijintv
[线程 8] 存储房间: http://www.douyu.com/327140
[线程 1] 存储房间: http://www.douyu.com/1733204
[线程 7] 存储房间: http://www.douyu.com/318812
[线程 8] 存储房间: http://www.douyu.com/550538
[线程 9] 存储房间: http://www.douyu.com/1089301
[线程 1] 存储房间: http://www.douyu.com/1529776
[线程 7] 存储房间: http://www.douyu.com/psp968968
[线程 19] 获得房间: http://www.douyu.com/1569173
[线程 8] 存储房间: http://www.douyu.com/697983
[线程 1] 存储房间: http://www.douyu.com/keer
[线程 19] 存储房间: http://www.douyu.com/thp
[线程 9] 存储房间: http://www.douyu.com/1652743
[线程 7] 存储房间: http://www.douyu.com/xiaoermi
[线程 5] 获得房间: http://www.douyu.com/qldyu
[线程 8] 存储房间: http://www.douyu.com/dayage
[线程 1] 存储房间: http://www.douyu.com/921537
[线程 19] 存储房间: http://www.douyu.com/rentoudage
[线程 7] 存储房间: http://www.douyu.com/1448875
[线程 9] 存储房间: http://www.douyu.com/1586681
[线程 8] 存储房间: http://www.douyu.com/ACE4j4f
[线程 1] 存储房间: http://www.douyu.com/101581
[线程 9] 存储房间: http://www.douyu.com/688037
[线程 19] 存储房间: http://www.douyu.com/beizile
[线程 7] 存储房间: http://www.douyu.com/SuperDongGua
[线程 8] 存储房间: http://www.douyu.com/1632941
[线程 5] 获得房间: http://www.douyu.com/638494
[线程 9] 存储房间: http://www.douyu.com/1480484
[线程 19] 存储房间: http://www.douyu.com/1707082
[线程 1] 存储房间: http://www.douyu.com/dandansimida
[线程 7] 存储房间: http://www.douyu.com/234796
[线程 8] 存储房间: http://www.douyu.com/biersi
[线程 9] 存储房间: http://www.douyu.com/973430
[线程 8] 存储房间: http://www.douyu.com/700699
[线程 1] 存储房间: http://www.douyu.com/1704340
[线程 7] 存储房间: http://www.douyu.com/431834
[线程 19] 存储房间: http://www.douyu.com/hekang26
[线程 9] 存储房间: http://www.douyu.com/1448831
[线程 8] 存储房间: http://www.douyu.com/1056129
--------------------------------------------
[线程 16] 存储房间: http://www.douyu.com/1752254
[线程 16] 存储房间: http://www.douyu.com/432194
[线程 16] 存储房间: http://www.douyu.com/1022771
[线程 16] 存储房间: http://www.douyu.com/1433889
[线程 16] 存储房间: http://www.douyu.com/1507464
[线程 16] 存储房间: http://www.douyu.com/1609845
[线程 16] 存储房间: http://www.douyu.com/1714938
[线程 16] 存储房间: http://www.douyu.com/1733278
[线程 16] 存储房间: http://www.douyu.com/1733857
[线程 16] 存储房间: http://www.douyu.com/1756482
[线程 16] 存储房间: http://www.douyu.com/1762073
[线程 16] 存储房间: http://www.douyu.com/1763143
[线程 16] 存储房间: http://www.douyu.com/560975
[线程 16] 存储房间: http://www.douyu.com/1107272
[线程 16] 存储房间: http://www.douyu.com/1507653
[线程 16] 存储房间: http://www.douyu.com/1696140
[线程 16] 存储房间: http://www.douyu.com/1747240
[线程 16] 存储房间: http://www.douyu.com/1756615
[线程 16] 存储房间: http://www.douyu.com/1763597
[线程 16] 存储房间: http://www.douyu.com/1576127
[线程 16] 存储房间: http://www.douyu.com/1715281
[线程 16] 存储房间: http://www.douyu.com/1751258
[线程 16] 存储房间: http://www.douyu.com/289467
[线程 16] 存储房间: http://www.douyu.com/588167
[线程 16] 存储房间: http://www.douyu.com/992747
[线程 16] 存储房间: http://www.douyu.com/441593
[线程 16] 存储房间: http://www.douyu.com/wangjiayuan
[线程 16] 存储房间: http://www.douyu.com/941643
[线程 16] 存储房间: http://www.douyu.com/zgzx
[线程 16] 存储房间: http://www.douyu.com/709507
[线程 16] 存储房间: http://www.douyu.com/1157338
[线程 16] 存储房间: http://www.douyu.com/1127329
[线程 16] 存储房间: http://www.douyu.com/1584630
[线程 16] 存储房间: http://www.douyu.com/1450321
[线程 16] 存储房间: http://www.douyu.com/1642714
[线程 16] 存储房间: http://www.douyu.com/1064505
[线程 16] 存储房间: http://www.douyu.com/1146092
[线程 16] 存储房间: http://www.douyu.com/680754
[线程 16] 存储房间: http://www.douyu.com/69832
[线程 16] 存储房间: http://www.douyu.com/1026872
[线程 16] 存储房间: http://www.douyu.com/810070
[线程 16] 存储房间: http://www.douyu.com/woshidaxiang
[线程 16] 存储房间: http://www.douyu.com/607602
[线程 16] 存储房间: http://www.douyu.com/1233613
[线程 16] 存储房间: http://www.douyu.com/1635785
[线程 16] 存储房间: http://www.douyu.com/1708780
[线程 16] 存储房间: http://www.douyu.com/1729768
[线程 16] 存储房间: http://www.douyu.com/726729
[线程 16] 存储房间: http://www.douyu.com/1560522
[线程 16] 存储房间: http://www.douyu.com/1055832
[线程 16] 存储房间: http://www.douyu.com/1661439
[线程 16] 存储房间: http://www.douyu.com/1727351
[线程 16] 存储房间: http://www.douyu.com/1754653
[线程 16] 存储房间: http://www.douyu.com/856456
[线程 16] 存储房间: http://www.douyu.com/1344011
[线程 16] 存储房间: http://www.douyu.com/1471174
[线程 16] 存储房间: http://www.douyu.com/1763018
[线程 16] 存储房间: http://www.douyu.com/428860
[线程 16] 存储房间: http://www.douyu.com/692988
[线程 16] 存储房间: http://www.douyu.com/63279
[线程 16] 存储房间: http://www.douyu.com/dxyd
[线程 16] 存储房间: http://www.douyu.com/1733399
[线程 16] 存储房间: http://www.douyu.com/1091684
[线程 16] 存储房间: http://www.douyu.com/1547628
[线程 16] 存储房间: http://www.douyu.com/779076
[线程 16] 存储房间: http://www.douyu.com/1251518
[线程 16] 存储房间: http://www.douyu.com/1729363
[线程 16] 存储房间: http://www.douyu.com/1056938
[线程 16] 存储房间: http://www.douyu.com/balaosiji
[线程 16] 存储房间: http://www.douyu.com/734565
[线程 16] 存储房间: http://www.douyu.com/1478684
[线程 16] 存储房间: http://www.douyu.com/1667059
[线程 16] 存储房间: http://www.douyu.com/1459180
[线程 16] 存储房间: http://www.douyu.com/caopan
[线程 16] 存储房间: http://www.douyu.com/1064081
[线程 16] 存储房间: http://www.douyu.com/554746
1
golmic 2017-02-24 21:11:18 +08:00
既然想并发的话为什么不用 scrapy
|
2
kindjeff 2017-02-24 21:12:04 +08:00
虽然你的问题我不知道具体的答案,但是要知道 CPython 是禁止多线程同时工作的,同一时刻只有一个线程在工作,遇到 I/O 才会切换到另一个线程。你这个程序每个线程每次都循环写入文件肯定是不合理的,需要优化。另外 Python 并发编程最合理的办法应该是不用多线程……
|
3
Yinz 2017-02-24 23:49:03 +08:00
多打一些 log ,尽可能找出每个线程是卡在哪一句上,曾经有过类似的经历,是因为某些线程卡在了 html parse 上,原本单线程很快的 cpu 操作变得异常的慢。后来把 parse 的操作解耦放到另一个进程里面就顺畅很多了。
|
4
kevin100702 2017-02-25 00:04:01 +08:00 via Android
不是不推荐多线程?用子进程
|
5
LINAICAI 2017-02-25 00:21:27 +08:00
线程不是你想开多少就有多少,跟系统 cpu 有关。
|
6
binux 2017-02-25 00:27:04 +08:00
你不处理异常的吗?
|
7
binux 2017-02-25 00:30:50 +08:00
为什么一开始频繁的使用几个线程?线程是同时执行的
为什么先获取一段时间,然后再存储?你自己这么写的,别人怎么知道为什么! 为什么最后只有线程 16 在工作?你加锁了啊! 下方代码如何修改才能将多线程做到最佳?不用多线程 |
8
Mistwave 2017-02-25 00:40:44 +08:00
Python 有 GIL ,多线程不是很好用,一般使用协程做并发
前几天看到一篇好文章,分享在此 “从 0 到 1 , Python 异步编程的演进之路”: https://zhuanlan.zhihu.com/p/25228075 |
9
binux 2017-02-25 00:43:42 +08:00
不对,我就不懂了,你这个 rooms_queue 也不共享,锁也不共享,你放这有什么用呢。。
为什么最后只有线程 16 在工作?因为它干得最慢啊 |
10
PythonAnswer 2017-02-25 01:27:32 +08:00 via Android
2017 了, async await 都普及到 js 啦。
|
11
ryd994 2017-02-25 02:46:14 +08:00
明明是个队列需求,就好好用队列库
锁也不会用 |
13
likuku 2017-02-25 09:53:29 +08:00
线程处理任务队列,任务异步执行,多子进程处理任务,子进程统统后台执行。
如此这般, python 才会真正用到多核 /超线程 处理能力。 |