专题系列导引

  爬虫课题描述可见:

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

  课题解决方法:

微博移动版爬虫

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

微博PC网页版爬虫

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



前言

  前面【一】中我们介绍了移动版微博的爬虫方式,程序实现简单,运行稳定可靠,但有其弊端,爬取数据不全。
  从本文开始我们分析网页版微博爬取的实现方式,能较好的全量爬取所有数据

一. 分析

微博辟谣的URL地址:

https://weibo.com/weibopiyao?is_all=1

微博页面效果:

爬取思路

  首先分析PC网页版微博的网站设计和HTML页面结构。发现PC网页版特点如下:

  1. 网页版微博的实现方式跟移动版不同,不是调用API接口再进行渲染,而是用了前端工程框架。在访问网址URL时,将当页数据就全部在js中返回了,在<script>FM.view({})</script>中可以看到数据对象,每页微博HTML约加载45条微博数据对象:

    此数据对象比较复杂,不好从中直接解析出所需要的的微博字段。如选取解析此html数据,则需要用到Beautiful Soup工具,读者可以自行尝试,此博文没有采用此种方法

对于Beautiful Soup工具,可以参考:Python 爬虫利器二之 Beautiful Soup 的用法

  1. 前端页面加载方式

a. 下拉:每个页面默认先只展示15条微博数据;通过下拉到页面底端,前端框架再从FM.view()中加载接下来的15条微博数据,进行页面渲染,并使得下拉条变长;每个页面可以下拉两次,两次到底后,整个页面加载约45条数据。
b. 翻页:当本页下拉两次到底后,所有FM.view()中的数据对象都被渲染完毕,此时页面底端则不再出现渲染进度动画,而是出现button按钮:“上一页”、“下一页”,还有页面选择的下拉列表selector(如下图)
c. 当点击下一页时,服务器会返回下一页的整个HTML,整个页面窗口会重新渲染下一页的内容。每页的HTML格式都一致:45条数据在FM.view()中,每次展示15条,可以下拉两次

  1. 微博PC网页版浏览时需要登录状态。否则微博会在翻页操作时,不定期弹出“登录tab”页让用户登录;此种情形下,用户可能只浏览若干页微博数据,就被打断;若编写爬虫程序,则可能会打断爬取,造成失败

结论

  综上所述,对于微博PC网页版,我们采用** “分析页面html,提取元素内容” **的方式进行爬取更为适合。因此我们用到python爬取工具包:Selenium

对于Selenium工具,可以参考官方网站说明:http://www.selenium.org.cn/,其中有很多介绍和API说明文档,还提供了使用案例可以学习

二. 处理流程

  整个微博爬取流程,可以梳理为:

 1. 进入微博页面,输入用户名密码进行登录,处理必要的验证2. 登录完成后,进入“微博辟谣”首页,进行下拉页面操作,加载隐藏的内容,连续下拉两次,加载完整个页面45条微博内容3. 爬取整个页面的微博内容,将45条数据提取4. 点击“下一页”,加载下一页的页面数据,并循环下拉两次到底,开始爬取此页内容5. 循环往复不断爬取每页的全量数据,直到最后一页,最后保存excel,爬取结束

三. 代码实现

1. 项目结构

  Python爬虫工程使用selenium工具类,采用面向对象编程。
  结构如下:

  • 创建Crawler类,处理微博页面的下拉、翻页,和爬取数据的功能,最终把数据存储起来(存储结构化表格数据最好用pandas.DataFrame)。写入line_crawl.py模块内
  • 下用Crawler类爬取页面之前,需要先提前进行一些预处理,比如加载driver驱动、登录微博等操作;爬取完成后,还需要将数据写入Excel。因此定义一个CrawlHandle类,串联整个爬取逻辑,实现预处理和后面的数据写入。中间部分的爬取逻辑还是交给Crawler对象来实现,因此CrawlHandle类串联方法中,需将Crawler对象作为入参。写入crawl_handle.py模块内

以上两个处理模块,放在名为pc包中

  • 因为DataFrame数据写excel比较基础,所以我们将它设计为一个工具方法。定义一个util.py模块,将工具方法都写入此模块中
  • 项目中URL、写入地址、表头等配置变量比较多,因此将他们写入property.py文件

以上两个公共模块,放在名为common的包中

  • 在项目下创建一个名为excel的文件夹,将最终的导出结果文件存于其中
  • main.py作为整个项目的启动入口

最终项目结构如下图:

2. main.py

  main.py为程序入口,启动工程时首先执行。因为我们的串联类为CrawlHandle,并且需要Crawler做为入参,因此代码设计如下:

if __name__ == '__main__':# 创建handle类对象crawl_handle = crawl_handle.CrawlHandle()# 创建Crawler对象crawler = line_crawl.Crawler()# 网页版微博爬取crawl_handle.crawl_wb_and_write_excel(crawler)

3. CrawlHandle类

  CrawlHandle类为爬取处理类,根据上面的设计,定义一个串联方法:def crawl_wb_and_write_excel(),设计如下:


class CrawlHandle:"""微博爬取handle类,串联整个爬取和写excel过程"""def crawl_wb_and_write_excel(self, crawler):"""主方法:加载浏览器驱动、登录,爬取微博网页版中的数据,整理并存入指定excel:return:"""try:# 1 加载驱动driver = self.create_driver(15)# 2. 加载首页面,并进行登录cookies = self.login(driver)# 3. 不断爬取所有微博内容数据,具体处理逻辑有crawler方法自己实现# TODO  在设计Crawler时去实现此处调用# 4. 关闭驱动crawler.quit_driver()# 5. 爬取完所有微博后,进行写文档操作crawler.write_excel()except Exception:print("爬虫程序报错,可能出现问题,请检查!")traceback.print_exc()

  那么接下来的重点就是补充完这五部分的方法代码细节,定义相关的类或者方法

a.加载驱动

驱动的加载相对独立,只有串联方法调用。因此可以看做是CrawlHandle类的一个方法,编写如下:

    def create_driver(self, wait_time=3):"""启动chrome驱动,并加载URL页要提前下载与本机Chrome版本相同的chrome驱动到本地电脑内,并将文件路径设置入环境变量path,并重启IDE# chrome驱动下载地址: https://npm.taobao.org/mirrors/chromedriver"""# 1. 加载chrome浏览器驱动driver = webdriver.Chrome()print("Chrome驱动启动成功!")# 2. 设置隐性等待时间driver.implicitly_wait(wait_time)return driver

注意

必须先按照本地电脑的操作系统类型以及已经安装好的Chrome版本,下载好匹配的selenium驱动并配置好环境变量,才能正常启动驱动;否则报错。
chrome驱动下载地址: https://npm.taobao.org/mirrors/chromedriver

b.登录微博

  driver驱动弹出chrome浏览器,打开微博辟谣首页(或者是其他首页),模拟点击右上角“登录”按钮,弹出登录收入框tab页,输入必要的用户名、密码后,再点击“登录”,完成登录操作

注意:

  1. 模拟点击微博右上角的“登录”按钮时,chrome浏览器有一定概率不是直接弹tab框,而是会首先跳转passport.weibo.com;当用户登录完成后再跳回“微博辟谣”首页。此种情况下,程序自动填写表单可能会报错,提示找不到元素,则需要重启程序(也可以在程序中多加分析判断这种情况【通过URL的变化】再针对性的自动填表,博文为了节省时间没有进行处理)
  2. 有时候登录完成后,微博并非会跳转回“微博辟谣”首页,而是跳转回“用户中心”首页。如果此时立刻爬取内容,则可能会出现爬取内容不正确,或者报错找不到元素。因此登录完成后,让程序等待一段时间,并不断监测当前页URL,若未跳转“微博辟谣”,首页,则主动加载首页。等页面跳转回来再进行后续操作
  3. 微博登录有时填写完用户名密码还不行,仍然会弹出一个二维码,让用户用微博APP客户端扫码认证,或者弹出图形验证码、手机验证码让用户再次校验,通过后才可以登录成功。因此爬虫程序也得在后台等待、轮询监测二次验证完成,页面真正跳转“微博辟谣”首页后,才算整个登录过程完成

额外需要注意

  • 受电脑运行速度、本地wifi网络速度影响,在不同环境下,本程序执行爬取页面的运行速度也不一样。而浏览器对Web页面渲染是渐进式加载的,有时候页面未完全加载完成,浏览器已经有了显示,爬虫程序也开始了后续操作。此时可能js、css仍未生效,因此在用selenium操作时,可能会出现“爬取错误,页面报错”的情况。这种情况并非只在登录时会发生,而是在整个爬取过程中,都有可能出现,引起爬取报错失败
    因此各位需要结合自己本地网络和电脑配置情况,调整程序内的等待时间(time.sleep()的数值),确保页面完全加载完成后,后续填表或者爬取的逻辑才会执行

此方法也可以看做是CrawlHandle类的一个方法;编写如下:

    def login(self, driver):"""加载网页版微博首页面,并进行登录:return:"""# 1. 打开微博辟谣URL,加载首页面# 注意: 模拟点击微博右上角的“登录”按钮时,chrome浏览器有可能不是直接弹tab框,而是会首先跳转passport.weibo.com,让用户登录完成后再跳回“微博辟谣”首页。# 此时程序自动填写表单可能会报错,提示找不到元素,则需要重启程序driver.get(WB_PIYAO_URL_PAGE % 1)print("加载 URL = %s" % WB_PIYAO_URL_PAGE % 1)# 2. 进行登录操作login_btn = driver.find_element_by_xpath("//a[@node-type='loginBtn']")login_btn.click()print("打开登录窗口... ")# time.sleep(0.5)# 输入用户名密码driver.find_element_by_xpath("//input[@name='username']").send_keys(USERNAME)driver.find_element_by_xpath("//input[@name='password']").send_keys(PASSWORD)print("输入用户名:%s   密码:%s " % (USERNAME, PASSWORD))# 点击登录按钮submit_btn = driver.find_element_by_xpath("//a[@node-type='submitBtn']")submit_btn.click()print("点击登录按钮......")# 微博做了防自动登录操作,页面仍有可能要输入验证码、手机扫码。此时需手动操作time.sleep(2)   # 让微博登录后,有足够时间跳转到下一页面while WB_PIYAO_URL not in driver.current_url or not util.is_element_exist_by_css_selector(driver, "div.gn_set"):print("登录仍未成功,需要在页面处理...")# 如果页面已跳转到用户首页,则需再次加载微博辟谣首页if "weibo.com/u/" in driver.current_url:driver.get(WB_PIYAO_URL_PAGE % 1)time.sleep(2)else:print(" 登录微博成功,开始爬取... ")# 最好休息一下,让新页面跳转出来,再获取cookiestime.sleep(1)# 获取登录后的cookiescookies = driver.get_cookies()print("登录成功,获得cookie:%s" % cookies)# 将隐性时间再设小,以提高效率。 如果网络不好,则数值应该大一些,以防找不到element报错driver.implicitly_wait(1)return cookies
d. 全部爬取完毕后,关闭driver

  步骤4为关闭driver,由Crawl类实现

    def quit_driver(self):self.driver.quit()
e. 爬取完所有微博后,进行写文档操作

  步骤5:爬取完所有微博后,进行写文档操作。由Crawl类实现,可以设计成一个工具方法,入参为df数据集,以及文件保存的地址,利用df自带的方法:to_excel()实现

    def write_excel(self):util.write_excel(self.excel_df, WB_EXCEL_PATH)
# util.py工具方法
def write_excel(excel_df, excel_path):"""将结果写入Excel:param excel_df::param excel_path::return:"""print("开始写入Excel文档:文档名称 %s" % excel_path)excel_df.to_excel(excel_path, index=False)print("写入Excel文档成功!")

4. Crawl类

  正如上面分析,Crawl类主要完成串联方法中的步骤3,因此定义结构如下:

class Crawler:"""爬取类,负责下拉、爬取、翻页,将最终结果存入df"""def __init__(self):"""初始化处理类所需必要的属性"""# 定义空df,以装载处理完的数据self.excel_df = DataFrame(columns=EXCEL_COLUMNS)# 声明driverself.driver = Nonedef crawler_all_wb_and_save_df(self):"""不断爬取所有微博内容数据,并存入excel_df最末端:return:"""try:# 当前处理第几页self.page = 1# 没到最后一页,则一直循环while True:# 1. 下拉2次至本页最底端,会出现分页按钮for i in range(2):print("  下拉到最底端操作,第 %i 次 ..." % i)self.driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")# 另一种下拉方法# element.sendKeys(Keys.END)# 为防止下拉时,新页面短时间加载不出来,让程序睡眠几秒等待time.sleep(1)# 补救措施:若3次下拉还不能到最底,还需再循环while not util.is_element_exist_by_css_selector(self.driver, "div[class='W_pages']"):print("  没下拉到最底端,再次下拉...")self.driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")# 为防止下拉时,新页面短时间加载不出来,让程序睡眠几秒等待time.sleep(1)# 2. 下拉完毕,展示全部内容后,爬取此页微博数据,并添加入df中self.__crawler_page_and_save_df()# 有时候翻页会失败。在此做检查,看看微博页面中的页数是否为程序中的页数,如不一致则提示wb_page_num = self.driver.find_element_by_css_selector(".W_pages>span>a").textwb_page_num = wb_page_num[2:-2].strip()if str(self.page) != wb_page_num:print("程序页面:%s 与微博页面:%s 不匹配,可能有翻页出错的情况,请检查!" % (self.page, wb_page_num))# 3. 检查是否有"下一页"按钮w_page = self.driver.find_element_by_class_name("W_pages")if "下一页" in w_page.text:self.page += 1# 如果有“下一页”,则翻页至下一页w_page_next = w_page.find_element_by_class_name("next")# 要用如下写法先移动到button上,再点击,,不然总是 ElementClickInterceptedExceptionwebdriver.ActionChains(self.driver).move_to_element(w_page_next).click(w_page_next).perform()# w_page_next.send_keys("\n")time.sleep(3)else:# 如果没有,则说明到了最后一页,整个爬取完成print("已经到最后一页,爬取微博完成")breakexcept:print("爬虫出现问题,先返回数据:excel_df")traceback.print_exc()

可以看到这个页面的逻辑就是:

1. 下拉两次
2. 爬取
3. 监测是否有下一页,如有则翻页并继续下拉爬取;没有则说明到最后一页,爬取结束返回
4. 所有数据都保存在self.excel_df的DataFrame数据集中
a. 爬取此页微博数据,并添加入df中

  爬取页面的逻辑在私有方法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")# 单线程执行,爬取框架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)
b. 爬取框架list中的微博数据,返回wb_list

  上面调用的方法def __sync_crawler_weibo_info()定义如下:

    def __sync_crawler_weibo_info(self, wb_cardwrap_list):"""同步爬取微博数据:return:"""wb_list = []  # 爬取到的微博信息整理后的储存listfor wb_count in range(len(wb_cardwrap_list)):# 逐个处理微博内容框架,取出必要字段组成json返回,并添加入返回的list中etl_json = util.crawler_weibo_info_func(wb_cardwrap_list[wb_count], self.page, wb_count)if etl_json:wb_list.append(etl_json)return wb_list

此方法实现的内容是:逐个处理微博内容框架,取出必要字段组成json返回,并添加入返回的list中。相对来说比较简单

c. 爬取框架内的微博数据

  此为核心代码,为爬取微博内容的方法。因为会被多次调用(随后探讨有关多线程爬取的实现也要用到),因此封装为工具函数,写在util.py模块中,如下:

def crawler_weibo_info_func(wb_cardwrap, page, wb_count):"""selenium提取网页版微博内容信息函数:param wb_cardwrap::param page::param wb_count::return:"""wb_content_start_time = time.time()try:# “微博辟谣”账号发微博时输入的文字内容wb_text = wb_cardwrap.find_element_by_class_name("WB_text").text# 若为'月度工作报告',则不进行统计if '月度工作报告' in wb_text:# 剔除月度工作报告,可打印日志分析剔除结果,以防有误判删除掉有用信息print("剔除月度报告: %s" % wb_text)return None# card转换整理后的json结果etl_json = {}# "微博辟谣"此条微博的idwb_id = wb_cardwrap.get_attribute("mid")# 微博名,这里为“微博辟谣”wb_name = wb_cardwrap.find_element_by_class_name("WB_info").text# “微博辟谣”账号发微博时微博时间wb_time = wb_cardwrap.find_element_by_class_name("WB_from").find_element_by_tag_name("a").get_attribute("title")# 本微博转发数,若为文章“转发”,则说明还没人转,设为0wb_repost_count = wb_cardwrap.find_element_by_class_name("WB_feed_handle").find_elements_by_tag_name("li")[1].find_elements_by_tag_name('em')[1].textwb_repost_count = 0 if "转发" == wb_repost_count else wb_repost_count# 原微博过长时,需要提取全文if "展开全文c" in wb_text:wb_long_text = get_weibo_long_text(wb_id)if wb_long_text is not None or wb_long_text != "":wb_text = wb_long_text# set值etl_json['WB_id'] = wb_idetl_json['WB_name'] = wb_nameetl_json['WB_text'] = wb_textetl_json['WB_time'] = wb_timeetl_json['WB_repost_count'] = wb_repost_count# 3. 判断是否转发他人微博# if is_element_exist(wb_cardwrap, 'div[node-type="feed_list_forwardContent"]'):    # 不用这个,当有图片时会比较慢wb_feed_expand = get_element_WB_feed_expand_if_exist(wb_cardwrap)if wb_feed_expand:# 原微博内容框架wb_cardwrap_org = wb_feed_expand.find_element_by_class_name("WB_expand")# 原微博内容,有可能出现转发账号注销、设置半年可见等失效等问题,无法爬取数据。此时需要判断# if not is_element_exist(wb_cardwrap_org, ".WB_empty"):    # 此方法太过耗时(7~15秒),因此用如下方法if not is_weibo_empty(wb_cardwrap_org):# 原微博的idwb_id_org = wb_cardwrap.get_attribute("omid")# 原微博号名称wb_name_org = wb_cardwrap_org.find_element_by_class_name("WB_info").text# 原微博发微时输入的文字内容wb_text_org = wb_cardwrap_org.find_element_by_class_name("WB_text").text# 原账号发微博时微博时间wb_time_org = wb_cardwrap_org.find_element_by_class_name("WB_from").find_element_by_tag_name("a").get_attribute("title")# 原微博转发数wb_repost_count_org = \wb_cardwrap_org.find_element_by_class_name("WB_func").find_elements_by_tag_name('li')[0].find_elements_by_tag_name('em')[1].textetl_json['WB_id_org'] = wb_id_orgetl_json['WB_name_org'] = wb_name_orgetl_json['WB_time_org'] = wb_time_orgetl_json['WB_repost_count_org'] = wb_repost_count_orgetl_json['type'] = "转发"etl_json['weibo_name'] = wb_name_orgetl_json['time'] = wb_time_orgetl_json['repost_count'] = wb_repost_count_org# 原微博过长时,需要提取全文if "展开全文c" in wb_text_org:wb_long_text_org = get_weibo_long_text(wb_id_org)# etl_json['wb_long_text_org'] = wb_long_text_org# 替换文本if wb_long_text_org is not None or wb_long_text_org != "":wb_text_org = wb_long_text_orgetl_json['WB_text_org'] = wb_text_orgetl_json['text'] = wb_text_orgelse:print("此条微博状态:'%s'   因此不可爬取。etl_json = %s" % (wb_cardwrap_org.text, etl_json))return None# 不是转发,则为原创else:etl_json['type'] = "原创"etl_json['weibo_name'] = wb_nameetl_json['text'] = wb_textetl_json['time'] = wb_timeetl_json['repost_count'] = wb_repost_countprint("    第 %i 页,第 %i 条数据处理完成,耗时:%s " % (page, wb_count, time.time() - wb_content_start_time))return etl_jsonexcept:print("    第 %i 页,第 %i 条数据处理出错! 请检查原因!" % (page, wb_count))traceback.print_exc()return None

以上整个爬虫项目编写完毕,只有配置变量和用到的工具方法没有贴出,具体实现可见源代码

四. 爬虫执行

1. 执行过程

    启动程序,会弹出chrome浏览器,开始加载微博辟谣首页,并进行登录(本例会弹出二维码,APP扫码后正式登录成功,开始下拉爬取)

可以看到后端不断的在爬取数据,是逐条进行的,每条月耗时0.8s,每页耗时约30s;共爬取约240页

1. 执行结果

    最后爬取存入excel的结果如下,前四列即为课题要求的结果,后面是额外爬取的其他内容

五. 问题总结

  1. 使用selenium爬取PC网页版微博时,必须先按照本地电脑的操作系统类型以及已经安装好的Chrome版本,下载好匹配的selenium驱动并配置好环境变量,才能正常启动驱动;否则报错。chrome驱动下载地址: https://npm.taobao.org/mirrors/chromedriver
  2. selenium爬取网页是模拟人操作页面浏览的方式,进行信息提取。因此实际执行中发现,如果程序执行find_element_by_XXX()、click()等查询和点击操作时,如果driver弹出的浏览器,有不限于如下的一些情况**(被最小化隐藏、被其他程序页面覆盖浏览器、要操作的对象还在滚动条区域内,没页面中显示、被其他可以click的标签比如消息提醒button布局覆盖等等)**,则selenium的操作会无法生效,甚至报错can’t find element,导致程序异常。这个问题在电脑全屏打开其他窗口时尤其容易发生,例如在看pycharm后端日志、打开其他浏览器全屏搜索问题。

因此在程序运行时,请保持driver浏览器始终在最顶端,显示窗口足够大,并在中途不要操作,等待爬取完成;同时,driver浏览器窗口需要保持一定的大小,当触发登录点击按钮、下拉到最低端点击下一页按钮时,都需要在chrome浏览器内能肉眼观测到这个元素

  1. 受本地网络速度影响,页面在不同环境下加载速度也不一样。而浏览器对Web页面渲染是渐进式加载的,有时候页面未完全加载完成,浏览器已经有了显示,爬虫程序也开始了后续操作。此时js还未生效、css加载不对,可能会出现爬取错误,页面报错的情况
  • 因此各位需要结合自己本地网络和电脑配置情况,调整程序等待时间,确保页面完全加载完成后,后续填表或者爬取的逻辑才会执行
  • 用try-except处理爬取异常的情况,尽量保留部分data数据写入excel
  • 也可以用selenium提供的隐式等待执行方法:driver.implicitly_wait(30) # 隐性等待,最长等30秒
  • 也可以用selenium提供的隐式等待执行方法:WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator))
  1. 本程序初稿编时间为2020年12月,整理发表时间为2021年3月20日,此时间点程序运行正常。但微博HTML页面会随时间而更新,因此有可能导致本程序selenium步骤执行失效。本程序旨在抛砖引玉,希望读者能从中获取灵感,开发出适合自己的版本
  2. 微博辟谣总共有约240页数据,每页30s;再加上下拉和翻页(约6s~9s的等待),则240页需要9120,约合2.5小时,时间耗时太久;一旦程序因为网络或者内存问题出现报错,则只能爬取保留下部分数据,功亏一篑。

解决方法是通过多线程快速爬取微博内容;多线程分为两种:

  1. 一种是在每个页面爬取45条数据时,进行多线程异步爬取,缩短每个页面的爬取时间;
  2. 另一种是同时异步启动多个driver驱动,数量为n;同时将微博辟谣240页数据分割为n份的piece,每个driver驱动负责分析爬取一部分piece,最后再汇总写入表格

以上两种多线程方法,我们会在后面的博文中进行探讨


执行程序

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

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

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

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

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

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

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

项目工程

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

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

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

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

    专题系列导引   爬虫课题描述可见: Python爬虫[零]课题介绍 – 对"微博辟谣"账号的历史微博进行数据采集   课题解决方法: 微博移动版爬虫 Python爬虫[一]爬取移 ...

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

    专题系列导引   爬虫课题描述可见: Python爬虫[零]课题介绍 – 对"微博辟谣"账号的历史微博进行数据采集   课题解决方法: 微博移动版爬虫 Python爬虫[一]爬取移 ...

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

    专题系列导引   爬虫课题描述可见: Python爬虫[零]课题介绍 – 对"微博辟谣"账号的历史微博进行数据采集   课题解决方法: 微博移动版爬虫 Python爬虫[一]爬取移 ...

  4. python爬虫之 爬取案例网页ajax请求的数据

    本篇案例以这个网站为例, 阿里云智能logo设计,用requests抓取这个网站页面的时候是抓取不到生成的logo图片的,因为数据不是直接就存储在html页面里的,ajax请求在不重新加载整个页面的情 ...

  5. python爬虫:爬取动态网页并将信息存入MySQL数据库

    目标网站 http://www.neeq.com.cn/disclosure/supervise.html 爬取网页该部分内容 网页分析 查看网页源代码发现没有表格部分内容,对网页请求进行分析 F12 ...

  6. python爬虫——如何爬取ajax网页之爬取雪球网文章

    效果图 传送门点击传送门 进入网站之后我们打开开发工具之后,往下滑时会出现一个接口(当然滑的越多接口越多) 我们通过对比两个及以上的接口进行分析它们的不同之处(这叫找规律) 可以发现max_id是在变 ...

  7. python爬取网页表格数据匹配,python爬虫——数据爬取和具体解析

    标签:pattern   div   mat   txt   保存   关于   json   result   with open 关于正则表达式的更多用法,可参考链接:https://blog.c ...

  8. Python爬虫 图片爬取简陋版

    Python爬虫 图片爬取简陋版 因为在自学Python 学了几天打算写一个爬虫,后来发现学的python的基础还要学库 于是花了好长时间查资料 终于写出来一个简陋版本的 东拼西凑还真让我搞成了 下面 ...

  9. python爬虫之爬取网页基础知识及环境配置概括

    记:python爬虫是爬取网页数据.统计数据必备的知识体系,当我们想统计某个网页的部分数据时,就需要python爬虫进行网络数据的爬取,英文翻译为 spider 爬虫的核心 1.爬取网页:爬取整个网页 ...

最新文章

  1. Podman又是什么新技术?它和Docker有啥区别?
  2. 基于ReactNative实现的博客园手机客户端
  3. 2011年排名前七位的Linux操作系统。
  4. Java8的十大新特性
  5. Smarty中的ob_start问题
  6. 微观经济学现代观点(Hal R. Varian) 复习题 1.1
  7. 课程笔记|吴恩达Coursera机器学习 Week1 笔记-机器学习基础
  8. stm32 内部sram大小_在SRAM、FLASH中调试代码的配置方法(附详细步骤)
  9. 苹果自研5nm芯片M1首次亮相,搭载新MacBook Air
  10. python_海龟绘图_画出奥运五环图---python工作笔记014
  11. Android文件命名规范
  12. AngularDart Material Design 选项树
  13. rspec Could not find table
  14. Microsoft Office Word、Excel 和 PowerPoint 文件格式兼容包
  15. EXCEL实现自动填充
  16. 移动定位业务之“A-GPS(辅助全球卫星定位系统)”
  17. Promise、then()、catch()详解
  18. 01-游戏分类与热点探索
  19. 跟老男孩学 Linux 运维:Web 集群实战
  20. 小妙招,教你从旅行网上下载各种美图和视频!

热门文章

  1. FPGA零基础学习:LED流水灯设计
  2. 华为 T2211 刷机 到 T5211
  3. dcmotor2双PWM的定时器分配,代码
  4. 【控制】滑模控制,滑模面的选择
  5. 设计模式重点模式实例代码分析
  6. java 交通绘图_Java模拟交通路况
  7. 将SuperMap iClient3D 9D(2019) for WebGL示例项目部署到iserver服务器上
  8. [韩国][喜剧][请别非礼我][RMVB/384M][中字][经典爆笑性喜剧]
  9. 智慧党建/党员双报到/党建积分系统/智慧党建小程序/党建云平台
  10. 用js实现双人五子棋小游戏