多线程爬取笑话集
快期末考试了,老师说要考多线程,上次刚好写了多线程爬取糗百,这次练手就想换一换网址,然后就选择了爬取笑话集,但发现了问题,它打印出来的编码我不认识
使用下面代码:
res=requests.get(url=new_url,headers=self.headers)
content=res.text
print(content)
得到数据库的内容乱码了:
然后你观察网页时可以看到它的charset并不是utf-8,如下图:
上面检测的编码是GB2312,注意到GBK是GB2312的超集,两者是同一种编码。
这时你就需要在代码中加一个编码命令:
res=requests.get(url=new_url,headers=self.headers)
res.encoding = 'gb2312' 或者 res.encoding = res.apparent_encoding
获取网页正确的编码格式
content=res.text 返回的结果是处理过的Unicode类型的数据
print(content)
这时你的编码就是你能看懂的模样了。
好了多线程在前面已经聊过了,这里也就这么一个小坑,就直接上代码了。
import requests
from queue import Queue
from threading import Thread,Lock
from lxml import etree
import pymongo
采集类
class crawlThread(Thread):
def __init__(self,threadName,pageQueue,dataQueue):
super().__init__()
self.threadName=threadName
self.pageQueue=pageQueue
self.dataQueue=dataQueue
self.headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}
def run(self):
url = 'http://www.jokeji.cn/list_{}.htm'
while True:
try:
page=self.pageQueue.get(block=False)
print('采集开始{}'.format(self.threadName))
new_url=url.format(page)
res=requests.get(url=new_url,headers=self.headers)
# res.encoding = 'gb2312'
res.encoding = res.apparent_encoding
content=res.text
self.dataQueue.put(content)
print('采集结束{}'.format(self.threadName))
except:
break
解析类
class parseThread(Thread):
def __init__(self,threadName,dataQueue,lock):
super().__init__()
self.threadName = threadName
self.dataQueue = dataQueue
self.lock = lock
def run(self):
while True:
try:
content=self.dataQueue.get(block=False)
print('开始解析{}'.format(self.threadName))
self.parse(content)
print('结束解析{}'.format(self.threadName))
except:
break
def parse(self,html):
html = etree.HTML(html)
res=html.xpath('//div[@class="list_title"]/ul/li')
for i in res:
try:
title=i.xpath('.//b/a/text()')[0]
comment=i.xpath('.//span/text()')[0]
date=i.xpath('.//i/text()')[0]
item={'标题':title,'评论':comment,'日期':date}
with self.lock:
self.save(item)
except:
pass
def save(self,item):
con=pymongo.MongoClient('localhost',27017)
db=con.joke
table=db.joke
table.insert_one(item)
启动函数
def main():
pageQueue=Queue()
dataQueue=Queue()
lock=Lock()
for page in range(1,11):
pageQueue.put(page)
采集线程
crawlList=['1号','2号','3号']
thread_crawl_list=[]
for threadName in crawlList:
c=crawlThread(threadName,pageQueue,dataQueue)
c.start()
thread_crawl_list.append(c)
for i in thread_crawl_list:
i.join()
解析线程
parseList = ['1号', '2号', '3号']
thread_parse_list = []
for threadName in parseList:
p = parseThread(threadName, dataQueue,lock)
p.start()
thread_parse_list.append(p)
for j in thread_parse_list:
j.join()
if __name__ == '__main__':
main()