1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Python爬虫【三】爬取PC网页版“微博辟谣”账号内容(selenium单页面内多线程爬取内容)

Python爬虫【三】爬取PC网页版“微博辟谣”账号内容(selenium单页面内多线程爬取内容)

时间:2021-01-19 18:26:35

相关推荐

Python爬虫【三】爬取PC网页版“微博辟谣”账号内容(selenium单页面内多线程爬取内容)

专题系列导引

  爬虫课题描述可见:

Python爬虫【零】课题介绍 – 对“微博辟谣”账号的历史微博进行数据采集

  课题解决方法:

微博移动版爬虫

Python爬虫【一】爬取移动版“微博辟谣”账号内容(API接口)

微博PC网页版爬虫

Python爬虫【二】爬取PC网页版“微博辟谣”账号内容(selenium同步单线程)

Python爬虫【三】爬取PC网页版“微博辟谣”账号内容(selenium单页面内多线程爬取内容)

Python爬虫【四】爬取PC网页版“微博辟谣”账号内容(selenium多线程异步处理多页面)

前言

  前面专题文章【二】中,我们编写了微博PC网页版单线程的爬虫方式。但执行速度较慢,需要约两个小时才能处理完成。

  此文我们对之前的程序略作改造,让其实现在每个页面内爬取45条数据时,进行多线程异步爬取,从而缩短每个页面的爬取时间,进而缩短整个爬取时间。

一.改造多线程

  对于整个设计流程,之前CrawlHandle串行方法内的逻辑没有问题,仍然是执行五个步骤。前面的启动driver、登录认证,后面的关闭driver、写入数据,都没有变化。

1. 入参改造

  唯一需要变化的是步骤三,此时Crawl类在爬取时,应该去选择是执行多线程还是单线程。因为是改造,所以我们用一个开关来控制Crawler是走单线程还是多线程,构造函数增加一个入参。

class Crawler:"""爬取类,负责下拉、翻页、爬取,将最终结果存入df"""def __init__(self, async_crawler_in_page=True):"""初始化处理类所需必要的属性"""self.async_crawler_in_page = async_crawler_in_page# 定义空df,以装载处理完的数据self.excel_df = DataFrame(columns=EXCEL_COLUMNS)# 声明driverself.driver = None

可以看到传入了一个新入参async_crawler_in_page,为true时走并发爬取,否则还是之前的串行爬取

2. 爬取逻辑改造

def __crawler_page_and_save_df()方法中,进行参数判断。改造如下:

def __crawler_page_and_save_df(self):"""使用selenium工具爬取当前微博页面信息:param page::param driver::return:"""wb_page_start_time = time.time() # 用于计时wb_list = []# print("开始爬取第 %i 页数据..." % self.page)try:# 1. 找出微博内容框架list,也就是每个微博内容块的集合# wb_cardwrap_list = driver.find_elements_by_xpath("//div[@action-type='feed_list_item']") #尽量不用xpath,提高效率wb_cardwrap_list = self.driver.find_elements_by_class_name("WB_feed_type")# XXX 改造点:进行判断if self.async_crawler_in_page:# 多线程处理,每个线程解析一个微博内容框架,从中提取所需数据wb_list = self.__async_crawler_weibo_info(wb_cardwrap_list)else:# 单线程处理, 爬取框架list中的微博数据,返回wb_listwb_list = self.__sync_crawler_weibo_info(wb_cardwrap_list)except:print("爬取处理 第 %i 页html数据时出错! ", self.page)traceback.print_exc()else:print("成功爬取第 %i 页数据,爬取有效微博数:%s, 处理本页数据耗时:%s " % (self.page, len(wb_list), time.time() - wb_page_start_time))# 不为空则写入df中if wb_list:self.excel_df = self.excel_df.append(wb_list)

3. 新建异步爬取方法

上面调用了异步并行处理新写的方法:def __async_crawler_weibo_info()

def __async_crawler_weibo_info(self, wb_cardwrap_list):"""用多线程方式异步并发爬取微博内容:param wb_cardwrap_list::return:"""wb_list = [] # 爬取到的微博信息整理后的储存listthread_list = []for wb_count in range(len(wb_cardwrap_list)):# 多线程:约18秒左右处理完45条数据,比单线程串行30~36秒左右减少一半时间。 Python多线程是伪多线程thread = util.WBCrawlerThread(util.crawler_weibo_info_func,(wb_cardwrap_list[wb_count], self.page, wb_count))thread_list.append(thread)thread.start()# 取结果for thread in thread_list:thread.join()# 去除None,将结果存入list中if thread.result:wb_list.append(thread.result)return wb_list

这里用到了python的并行处理逻辑,自定义多线程工具类WBCrawlerThread,继承python自有类Thread,如下:

class WBCrawlerThread(threading.Thread):"""多线程工具类"""def __init__(self, func, args=()):super(WBCrawlerThread, self).__init__()self.func = funcself.args = argsdef run(self):self.result = self.func(*self.args)def get_result(self):try:return self.resultexcept Exception:return None

可见:

多线程类构造函数入参第一项为function函数类型,第二项为function所需要的传参。这里我们是希望多线程进行爬取每个微博块内的微博数据,因此传的入参函数就是之前已经定义好的def crawler_weibo_info_func()函数(参见前一篇博文);后面的参数即为此函数执行时所需要传入的参数。def __async_crawler_weibo_info()方法内,程序为每个wb_cardwrap_list内的对象创建一个WBCrawlerThread对象进行异步爬取,因此总共启动约45个多线程执行爬取操作爬取完成后,将执行结果存入wb_list返回,与之前串行的数据格式和大小都一致

4. main调用改造

if __name__ == '__main__':# 网页版微博爬取,使用多线程crawler = line_crawl.Crawler(async_crawler_in_page=True)crawl_handle.crawl_wb_and_write_excel(crawler)

以上即为selenium单页面内多线程爬取内容的改造

二. 程序执行

  执行过程中,前面登录与单线程没区别;但当用户登录成功,下拉两次后,开始爬取时:可以看到后台不再是按微博上下顺序依次爬取、每条微博处理完成后打印日志的间隔时间也不再标准,而是有快有慢,符合并行处理的情况

三. 问题总结

  因为本地计算机性能有限,电脑CPU核心固定(一般都是2核到8核),因此实际上不可能45个多线程完全并发执行。并且有人分析python的Thread实现逻辑,发现其并非为真正的多线程,而是伪多线程并非真正做到多核高并发。因此最后爬取的结果来看,仍是存在先后排队 ,大多等待、少数执行的情况;但整体上多线程还是使用了更多的CPU资源,会提高整体的爬取效率。

  博主笔记本为酷睿i5二核,经测算每个页面的爬取效率可以提升一倍,原先一个页面串行爬取需要30s~36s,改造多线程后;用时约18s;结合下拉翻页,整个项目爬取时间缩短为1.7个小时

执行程序

项目工程编译了windows版本执行程序:微博数据采集python+selenium执行程序:WBCrawler.exe

执行项目前,需要下载selenium对应的浏览器驱动程序(driver.exe),并放在本机环境变量路径中,否则会报错。安装操作具体可见博客专题中的指导【二】

执行程序时,会在系统用户默认路径下,创建一个虚拟的python环境(我的路径是C:\Users\Albert\AppData\Local\Temp_MEI124882\),因此启动项目所需时间较长(约20秒后屏幕才有反应,打出提示),请耐心等待;也正因如此,执行电脑本身环境是可以无需安装python和selenium依赖包的;同时最后爬取保存的excel也在此文件夹下。

本项目采用cmd交互方式执行,因此等到屏幕显示:

选择爬取方式:1. 移动版微博爬取2. PC网页版微博爬取(单线程)3. PC网页版微博爬取(页面内多线程)4. PC网页版微博爬取(多线程异步处理多页面)

后,用键盘输入1~4,敲回车执行

此exe编译时,工程代码内编写的最终excel记录保存地址为:相对工程根路径下的excel文件夹;因此当本exe执行到最后保存数据时,会因为此excel文件夹路径不存在而报错。若在工程中将保存地址改为绝对路径(例如D:\excel\),再编译生成exe执行,则最终爬取数据可以正确保存

项目工程

工程参见:微博数据采集python+selenium工程:WBCrawler.zip

本专题内对源码粘贴和分析已经比较全面和清楚了,可以满足读者基本的学习要求。源码资源为抛砖引玉,也只是多了配置文件和一些工具方法而已,仅为赶时间速成的同学提供完整的项目案例。大家按需选择

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。