以爬取“学术状态帝”的状态为例。
初始化并登录:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
driver = webdriver.Chrome()
driver.get('http://www.renren.com/')
打开人人网首页,检查元素,分别获取email和password的xpath
清除框内信息,填入用户名和密码
driver.find_element_by_xpath("//*[@id='email']").clear()
driver.find_element_by_xpath("//*[@id='email']").send_keys("username")
driver.find_element_by_xpath("//*[@id='password']").clear()
driver.find_element_by_xpath("//*[@id='password']").send_keys("pwd")
找到登录键的XPath,执行登录
driver.find_element_by_xpath("//*[@id='login']").click()
因为执行登录后新网页还未刷出,driver.current_url 指向的还是是登录页面,即http://www.renren.com/,此时需要用WebDriverWait显式等待在执行搜索。
在搜索栏内输出公共主页的名字,按回车
WebDriverWait(driver, 5).until(lambda x: x.find_element_by_xpath("//*[@id='hd-search']"))
driver.find_element_by_xpath("//*[@id='hd-search']").send_keys(u'学术状态帝')
driver.find_element_by_xpath("//*[@id='hd-search']").send_keys(Keys.ENTER)
因为搜到的是全部内容,所以需要点击上边栏的公共主页按钮
WebDriverWait(driver, 5).until(lambda x: x.find_element_by_link_text(u"公共主页"))
driver.find_element_by_link_text(u"公共主页").click()
如果接下来立刻执行driver.find_element_by_link_text(u"学术状态帝").click(),可能会因为网页还没缓冲过来,就会跳转到错误页面
使用异常处理
for _ in xrange(5):
time.sleep(5)
try:
driver.find_element_by_link_text(u"学术状态帝").click()
break
except Exception, e:
driver.refresh()
else:
raise Exception
此时Chrome打开了一个新标签页,因此应选择新标签页进行操作
driver.switch_to_window(driver.window_handles[-1])
current_url = driver.current_url
driver.find_element_by_link_text(u'状态').click()
最后就是获取状态内容,执行翻页,直到最后一页
在这里遇到了三个问题,
- 如果直接执行driver.find_element_by_link_text(u'下一页').click()的话,因为下一页的按钮在网页底部,会报错:Element is not clickable at point ...,因此要用js来控制滚动条到网页底部。
- 未刷新到新的网页,获取的内容依然是旧网页的内容,因此这里记录的旧网页的url,与当前网页进行比较
- 大概运行5,6次会出现一次下图的错误,出现的页数也是随机的,目前不知道是什么原因,只能通过判断当前网页的状态数量来选择是否刷新网页。
最后的代码如下:
while True:
WebDriverWait(driver, 40, 1).until(lambda x:x.current_url!=current_url)
for _ in xrange(5):
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
fdoing_list = soup.find_all('h3')
if not len(fdoing_list):
driver.refresh()
time.sleep(3)
continue
for fdoing in fdoing_list:
text = fdoing.text.replace('学术状态帝\n: ', '')
break
current_url = driver.current_url
print current_url
if not soup.find('a', title="下一页"):
break
js="var q=document.documentElement.scrollTop=100000"
driver.execute_script(js)
driver.find_element_by_link_text(u'下一页').click()