用python selenium模拟浏览器获取某网站信息。整个项目只有两处需要手动输入:一处是登陆时的验证码,另一处是查询条件。第一处要实现自动获取验证码并输入需要较大工程,第二处完全可以实现程序输入,这里为了简便选择手动输入。模拟过程中等待网页或者网页元素加载的过程都采用time.sleep()方法设置固定时间,当网速较慢时可以将时间调大,也可以采用selenium标准的判断加载是否成功。
为保密需要,程序中的密码已隐藏,因此直接运行此程序无法登陆系统,且主页面网址也不能直接给出,但只要换成一个有登陆界面的网址即可。程序稍作修改便可应用于其他模拟浏览器爬虫项目!完整代码如下(程序后附运行结果图片):
(说明:文中涉及保密部分都用‘*****’代替了!)
# -*- coding: utf-8 -*-
"""
Created on Mon Aug 6 11:31:58 2018
@author: cgx
"""
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
import requests
import re
from bs4 import BeautifulSoup
import time
browser = webdriver.Chrome() #定义浏览器
def loginpage():
loginpage_url = '此处为登陆界面url,为保密需要无法给出'
browser.get(loginpage_url)
element = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "#randCode"))) #等待网页加载时间
browser.find_element_by_id('username').send_keys("*****") #输入账号
browser.find_element_by_id('password').send_keys("*****") #输入密码
time.sleep(15) #等待用户输入验证码
browser.find_element_by_xpath('//*[@id="loginButton"]').click() #自动点击‘登陆’按钮
time.sleep(3)
browser.find_element_by_xpath('//*[@id="nav"]/li[3]/a').click() #自动点击‘*****’按钮
time.sleep(3)
browser.switch_to_frame('main_c') #转到新跳转的网页
browser.find_element_by_xpath('//*[@id="toibcsWriter"]').click() # 自动点击‘*****’按钮
time.sleep(3)
window_handles = browser.window_handles #得到所有窗口的handle
browser.switch_to.window(window_handles[-1]) #跳转到新窗口
time.sleep(3)
browser.find_element_by_xpath('//*[@id="beApply"]').click() # 自动点击‘*****’按钮
time.sleep(10)
browser.switch_to_frame('main') # 转到新刷出的部分网页
browser.find_element_by_xpath('//*[@id="mainContent"]/form/div[3]/div[13]/button[1]').click() # 自动点击‘*****’按钮
time.sleep(3)
#获取列表页网页代码,得到每个个体信息
listpage_html = browser.page_source #获取网页代码
soup = BeautifulSoup(listpage_html,'lxml') #形成BS对象
total_pages = soup.select('#mainContent > div.widget-box.bgc_odd > div.widget-content > div.ng-scope > table > tfoot > tr:nth-of-type(2) > td > div > ul > li:nth-of-type(1) > span > font:nth-of-type(2)')
total_pages = int(total_pages[0].get_text())
for page_index in range(total_pages):
print('共:{} 页;当前第{}页!'.format(total_pages,page_index+1))
#获取列表页网页代码,得到每个个体信息
listpage_html = browser.page_source #获取网页代码
soup = BeautifulSoup(listpage_html,'lxml') #形成BS对象
# print(soup.prettify()) #格式化网页代码
danzhenghaos = soup.select('tbody > tr > td > a[ng-click="showQuotationDetail(a.voucherNo)"]') #得到list页中每个个体信息
for i_dzh in danzhenghaos:
print('客户单证号:{}'.format(i_dzh.get_text().strip()))
danzhenghao_i = i_dzh.get_text().strip()
browser.find_element_by_partial_link_text(danzhenghao_i).send_keys(Keys.ENTER) #找到单证号链接并点击进入
window_handles = browser.window_handles #得到所有窗口的handle
browser.switch_to.window(window_handles[-1]) #跳转到每个个体的详情页
detailspage_html = browser.page_source #获取每个个体详情页网页代码
soup = BeautifulSoup(detailspage_html,'lxml') #形成BS对象
detailspage_html = str(soup.get_text) #得到网页代码并转化为string类型
regular_equation = r'"optionDisplay".*?"(.*?)"' #从详情页中匹配目标信息
pattern = re.compile(regular_equation, re.S)
results = re.findall(pattern, detailspage_html)
if results == []: #判断匹配的结果是否为空
print(' !Warning: 该单号未获取到目标信息!')
continue
print(results[0])
time.sleep(1)
browser.close() #关闭当前详情页窗口
browser.switch_to.window(window_handles[-2]) #返回到列表页
browser.switch_to_frame('main') # 转到框架
time.sleep(1)
#点击‘下一页’
browser.find_element_by_partial_link_text('下一页').send_keys(Keys.ENTER)
time.sleep(3) #等待下一页弹出(这个等待很重要,否则得到的网页代码依然是前面的),还可以根据待加载的页面元素是否已经出现或可点击来判断是否已加载成功
def main():
loginpage()
if __name__ == '__main__':
print('The spider is working now, please wait……')
start = time.clock()
main()
end = time.clock()
print ('Total running time : {} s'.format(int(end-start)))
程序执行结果:
sorrry:模拟点击网页的图片因保密需要不能给出!
最终获得的目标信息: