豆瓣原创电子书每周推出数十本限时免费数目,一周免费期过后恢复原价。想着豆瓣原创书中有不少值得一看,便写了个脚本,免去一个个添加的烦恼。

使用了Windows下selenium+Python的组合,有较多的文档可以查阅,主要总结如下:

1、使用chrome浏览器:下载旧版本(52),新版本不兼容,下载chromedriver,放入chrome安装目录,于chrome.exe同目录,并添加到Path环境变量。

2、强大的元素定位:通过浏览器审查元素直接复制的xpath多为绝对定位,容易受网页结构调整的影响,稳定性不好。

  相对定位在确保唯一性的前提下,可以自己写,快准稳。一般通过@id段确保唯一,注意同类型list集的影响。

  xpath中by_link_text可以通过链接文字直接定位<a>元素,在用到特殊链接时很有效。

  by_xpath("//*[text()='限时特价']")  这个简直简单粗暴,直接定位文字内容。有点JS里innerHTML的意思。

3、标签页的切换:用handles = driver.window_handles 获取当前的标签页,再通过driver.switch_to.window(handles[1]) 切换。

4、元素过期:翻页和刷新页面后再获取元素,频频报错。一方面,刷新页面后必须进行新的元素获取,并操作新获取的元素,尽量把获取写在循环体内。

  另一方面,页面刷新时,网页的代码执行速度比网页渲染速度快,下面代码采取time.sleep(2)简单粗暴,强制延迟等待网页渲染完毕,再进行元素获取,否则报错元素不存在,或元素过期。

import selenium
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys driver=webdriver.Chrome()
#打开豆瓣主站
driver.get('https://www.douban.com/')
#最大化
driver.maximize_window()
#输入用户名,密码
driver.find_element_by_id('form_email').send_keys('********')
driver.find_element_by_id('form_password').send_keys('******')
#点击登录
time.sleep(1)
driver.find_element_by_xpath('//*[@id="lzform"]/fieldset/div[3]/input').click()
time.sleep(3)
#打开阅读
driver.find_element_by_xpath('//*[@id="db-global-nav"]/div/div[4]/ul/li[7]/a').click()
time.sleep(2)
#切换到新打开的窗口
handles = driver.window_handles
driver.switch_to.window(handles[1])
time.sleep(2)
#打开免费
driver.find_element_by_link_text('免费').click()
time.sleep(2) #需要爬的页数
page=3
#已购买数量
book_is_read=0
#未购买数量
book_not_read=0 #外循环循环翻页
for j in range(0,page+1):
#本页循环数量
page_end=0
thisbooklist=0
time.sleep(2)
#内循环循环本页20条
for i in range(0,20):
time.sleep(2)
#只爬每周限时可选
driver.find_element_by_xpath("//*[text()='限时特价']").click()
time.sleep(2)
#获取本页书籍列表
booklists=driver.find_elements_by_xpath("//li[@class='item store-item']")
page_end=0 for booklist in booklists:
#获取阅读标志
isread=booklist.find_element_by_xpath(".//div[@class='action-buttons']/a").get_attribute("class")
#检查是否已经购买
if 'read' in isread:
page_end=page_end+1
continue
thisbooklist=booklist
break
#循环至列表最后一项跳出循环
if page_end>19:break
#进入书籍详情
thisbooklist.find_element_by_xpath('.//div[1]/a/img').click()
time.sleep(1)
#点击购买
driver.find_element_by_xpath("//span[@class='icon-add-to-bookshelf']").click()
#点击确定
time.sleep(2)
driver.find_element_by_xpath("//*[@id='ark-dialog']/div[2]/div[2]/button[1]").click()
time.sleep(3)
#返回上一页
driver.back()
time.sleep(2)
#刷新
driver.refresh()
# 打开下一页
time.sleep(2)
#翻页
driver.find_element_by_xpath('/html/body/div/div/article/div[2]/div[2]/div/ul/li[10]/a').click() time.sleep(2)
driver.close()

最新文章

  1. &quot;NHibernate.Exceptions.GenericADOException: could not load an entity&quot; 解决方案
  2. python有超时的windows系统时间设置代码
  3. 【转】java架构师之路:JAVA程序员必看的15本书的电子版下载地址
  4. Android SharedPreference的使用
  5. MySQL基础学习(一) 命令行命令
  6. 评价指标ROC,PR
  7. connot resolve symbol R
  8. 使用Servlet实现图片下载
  9. C#中Math.Round()实现中国式四舍五入
  10. 【USACO】第一章总结
  11. Interger 与 int
  12. activiti5.15中文乱码问题
  13. javascript深入理解闭包
  14. angular-fullstack test
  15. Hibernate(四)——缓存策略+lazy
  16. poj2524
  17. Django知识总结
  18. [bzoj4906][BeiJing2017]喷式水战改
  19. 清北学堂 清北-Day1-R2-监听monitor
  20. [转] React风格的企业前端技术

热门文章

  1. 【转载】#336 - Declaring and Using a readonly Field
  2. LCT入门
  3. http协议的发展历史
  4. node.js 下使用 util.inherits 来实现继承
  5. 2018.8.2 Juint测试介绍及其命名的规范
  6. An error occurred at line: 1 in the generated java file问题处理
  7. extjs3EmptyText 上传自动清空的问题
  8. c/c++基础
  9. 牛客小白月赛1 I あなたの蛙が帰っています 【卡特兰数】
  10. 基于PHP的微信公众平台开发(TOKEN验证,消息回复)