专栏首页赖权华的笔记Python网络爬虫笔记(四):使用selenium获取动态加载的内容

Python网络爬虫笔记(四):使用selenium获取动态加载的内容

(一)  说明

上一篇只能下载一页的数据,第2、3、4....100页的数据没法获取,在上一篇的基础上修改了下,使用selenium去获取所有页的href属性值。

使用selenium去模拟浏览器有点麻烦,例如有300页就要点300次(按博客园这种一页20条,也就是6000条数据。要是几百万条,这个就得点好长时间了)

研究下有没有办法调用JS修改页面默认显示的数据条数(例如:博客园默认1页显示20条,改成默认显示1万条数据)。

(二)  完整代码

delayed.py的代码还是和之前一样。最好限速,不限速很容易被拒绝连接,而且也不道德。

  1 from selenium import webdriver
  2 from selenium.webdriver.support.ui import WebDriverWait
  3 from selenium.webdriver.support import expected_conditions
  4 from selenium.webdriver.common.by import By
  5 from selenium.webdriver.support.expected_conditions import StaleElementReferenceException
  6 import time
  7 import urllib.request as ure
  8 from delayed import WaitFor
  9 import lxml.html
 10 import os
 11 import docx
 12 #使用selenium获取所有随笔href属性的值,url只能传小类的,例如https://www.cnblogs.com/cate/python/
 13 def selenium_links(url):
 14     driver = webdriver.Chrome()
 15     driver.maximize_window()
 16     driver.get(url)
 17     #获取最大页数
 18     maxPage = driver.find_element_by_css_selector('#paging_block div.pager a:nth-last-of-type(2)').get_attribute('text')
 19     x=1
 20     url_list=[]
 21     #循环获取当前小类所有页面的href
 22     while x<=int(maxPage):
 23         time.sleep(1) #隐式 显式等待都尝试了,还是报错,只能等待1秒了(调试又正常运行)
 24         x +=1
 25         #等待 Next出现并返回 ,就是博客园翻到下一页的那个元素
 26         lastPage = WebDriverWait(driver, 30).until(expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, '#paging_block div.pager a:last-child')))
 27         #等待元素出现并返回list,这里定位的是页面上的随笔
 28         html = WebDriverWait(driver, 30).until(expected_conditions.presence_of_all_elements_located((By.CSS_SELECTOR, 'a.titlelnk')))
 29         #迭代,将href属性的值添加到url_list
 30         for h in html:
 31             url_list.append(h.get_attribute('href'))
 32         lastPage.click()
 33     driver.quit()
 34     #以列表形式返回所有URL
 35     return url_list
 36 #传入包含url的列表
 37 def link_crawler(seed_url):
 38     html_list = []
 39     #下载crawl_queue中的所有网页
 40     waitFor = WaitFor(2)
 41     x =1
 42     while seed_url:
 43         print('第'+str(x)+'个')
 44         x+=1
 45         url = seed_url.pop()
 46         #下载限速
 47         waitFor.wait(url)
 48         html = download(url)
 49         html_list.append(html)
 50     return html_list
 51 #下载网页并返回
 52 def download(url,user_agent='FireDrich',num=2):
 53     print('下载:'+url)
 54     #设置用户代理
 55     headers = {'user_agent':user_agent}
 56     request = ure.Request(url,headers=headers)
 57     try:
 58         #下载网页
 59         html = ure.urlopen(request).read()
 60     except ure.URLError as e:
 61         print('下载失败'+e.reason)
 62         html=None
 63         if num>0:
 64             #遇到5XX错误时,递归调用自身重试下载,最多重复2次
 65             if hasattr(e,'code') and 500<=e.code<600:
 66                 return download(url,num-1)
 67     return html
 68 
 69 #将下载的网页写入Word文档
 70 def createWord(html):
 71     x = 0
 72     while html:
 73         url = html.pop()
 74         tree = lxml.html.fromstring(url)  # 解析HTML为统一的格式
 75         title = tree.xpath('//a[@id="cb_post_title_url"]')  # 获取标题
 76         the_file = tree.xpath('//div[@id="cnblogs_post_body"]/p')  # 获取正文内容
 77         pre = tree.xpath('//pre')  # 获取随笔代码部分(使用博客园自带插入代码功能插入的)
 78         img = tree.xpath('//div[@id="cnblogs_post_body"]/p/img/@src')  # 获取图片
 79         # 修改工作目录
 80         os.chdir('F:\Python\worm\data\博客园文件')
 81         try:
 82             # 创建一个空白新的Word文档
 83             doc = docx.Document()
 84             # 添加标题
 85             doc.add_heading(title[0].text_content(), 0)
 86         #有的设置成注册用户才能浏览的随笔,调用download函数时下载不到正确的网页,导致获取不到标题
 87         #title会是空列表,这里忽略这篇随笔,利用http.cookiejar模块应该可以解决这种问题,以后再看看这个模块了
 88         except IndexError as e:
 89             continue
 90         for i in the_file:
 91             # 将每一段的内容添加到Word文档(p标签的内容)
 92             doc.add_paragraph(i.text_content())
 93         # 将代码部分添加到文档中
 94         for p in pre:
 95             doc.add_paragraph(p.text_content())
 96         # 将图片添加到Word文档中
 97         for i in img:
 98             try:
 99                 ure.urlretrieve(i, '0.jpg')
100                 doc.add_picture('0.jpg')
101             except UnicodeEncodeError as e:
102                 print('异常'+str(e))
103                 pass
104         # 截取标题的前8位作为Word文件名
105         filename = title[0].text_content()[:8] + '.docx'
106         # 保存Word文档
107         # 如果文件名已经存在,将文件名设置为title[0].text_content()[:8]+ str(x).docx,否则将文件名设置为filename
108         if str(filename) in os.listdir('F:\Python\worm\data\博客园文件'):
109             doc.save(title[0].text_content()[:8] + str(x) + '.docx')
110             x += 1
111         else:
112             doc.save(filename)
113 #调用selenium_links获取所有url
114 html = selenium_links('https://www.cnblogs.com/cate/ruby/')
115 #调用link_crawler下载所有网页
116 downHtml = link_crawler(html)
117 #提取已经下载的网页数据到Word文档中
118 createWord(downHtml)

(三)结果

下面这个异常是,有的随笔上传了微信公众号的图片(暂时不确定是全部这样,还是部分这样),解析这个的时候会出现编码错误,目前的处理是输出异常信息,跳过这张图片。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python网络爬虫笔记(三):下载博客园随笔到Word文档

    (一)   说明 在上一篇的基础上修改了下,使用lxml提取博客园随笔正文内容,并保存到Word文档中。 操作Word文档会用到下面的模块: pip insta...

    free赖权华
  • Python网络爬虫笔记(二):链接爬虫和下载限速

    (一)代码1(link_crawler()和get_links()实现链接爬虫) 1 import urllib.request as ure 2 impo...

    free赖权华
  • Python Django框架笔记(六):模板

    free赖权华
  • Python可以做哪些好玩的事之将喜欢的博客整理成pdf1.采集数据2.将网页转换为pdf

    开篇之前,想打一波硬广(没(fen)广(si)告(fu)费(li)(ง •̀_•́)ง)。简书爸爸会不会打我? 天善智能,专注商业智能和数据库性能优化,如果你...

    Python攻城狮
  • Python秀操作 自动更换电脑壁纸

    原文链接:https://yetingyun.blog.csdn.net/article/details/112982010 创作不易,未经作者允许,禁止转载...

    叶庭云
  • Python基础学习_10_网页爬虫实战爬取百度百科词条(源码下载)

    下面使用Python开发一个网页爬虫,爬取百度百科词条信息,整个程序涉及到url管理器,html下载器,html解析器,html显示以及调度程序:

    码农帮派
  • 基于Python下载网络图片方法汇总代码实例

    本文介绍下载python下载网络图片的方法,包括通过图片url直接下载、通过re/beautifulSoup解析html下载以及对动态网页的处理等。

    砸漏
  • Linux系统下virtuoso数据库安装与使用详解

    最近在调研关联数据的一些东西,需要用到rdf数据库,所以接触了virtuoso数据库。安装的坑其实并不多,之前在windows 10上安过一次。这次在ubunt...

    砸漏
  • Linux系统下virtuoso数据库安装与使用详解

    最近在调研关联数据的一些东西,需要用到rdf数据库,所以接触了virtuoso数据库。安装的坑其实并不多,之前在windows 10上安过一次。这次在ubunt...

    砸漏
  • Callback ——从同步思维切换到异步思维

    这是一种非常常见的直线性思维,我先请求网站拿到 html,然后我再把 html 传给负责处理的函数。在整个过程中,“我“担任着调度的角色。

    青南

扫码关注云+社区

领取腾讯云代金券