以前我们爬虫用BeautifulSoup + requests组合来爬取我们所需要的信息。只要我们水平足够高,它不仅能爬取网上公开数据,也能爬取后台数据。但爬虫江湖也是有规则的(robots.txt),不遵从江湖规则很可能把自己爬进去。
用selenium爬取网页信息相对而言就好多了,它只是模拟人的上网动作,爬取网站让你获取的信息。
Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的。Selenium 可以直接调用浏览器,它支持微软的Edge、谷歌Chrome等主流浏览器。通过接收指令,让浏览器自动加载网站页面,获取所需要的数据,甚至还能给页面截屏。我们可以用selenium轻松完成以前需编写爬虫才能完成有工作。
一、创建一个Chrome驱动器
import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.action_chains import ActionChains
def webserver(): # 使用Chrome浏览器
# get直接返回,不再等待界面加载完成
desired_capabilities = DesiredCapabilities.CHROME
desired_capabilities["pageLoadStrategy"] = "none"
# 设置驱动器的环境
options = webdriver.ChromeOptions()
# 设置浏览器不加载图片,提高速度
options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
# 创建一个Chrome驱动器
driver = webdriver.Chrome(options=options)
return driver
二、打开相应网站页面
def open_page(): # 打开知网高级检索页面
# 打开页面,等待几秒
driver.get("https://kns.cnki.net/kns8/AdvSearch")
time.sleep(3) # 等待几秒,给网页一个加载时间,尤其网络不太好时
三、通过多种方式来定位标签
要模拟人的上网动作,无非是找到按钮(或链接)点击,在输入框中输入,或下拉框中选择等动作。如何定位按钮、链接、输入框、下拉框,就是重要的工作了。
用谷歌浏览器打开知网高级检索页面后,点击右上角三个竖点,从菜单中选更多工具-开发者工具,就出现下图:
如想选择“全选”复选框(点击全选二字也能勾选筛选框),可先点击箭头,再点击“全选”,就会出现红框中的内容,这也是全选对应的代码区域。如不能定位该区域,可在全选上右击,点检查就可定位了。
在该区域右击,出现菜单中选复制:
复制菜单后的内容,就是定位所需要的信息。
常见定位方法有:
driver.find_element(By.ID, 'id') # (返回一个元素)
driver.find_element(By.CLASS_NAME, 'calss_name') # (根据类名元素列表)
driver.find_element(By.NAME, 'name') # (根据标签的name属性值返回包含标签对象元素的列表)
driver.find_element(By.TAG_NAME, 'tag_name') # (根据标签名元素列表)
driver.find_element(By.CSS_SELECTOR, 'css_selector') # (根据css选择器来元素列表)
driver.find_element(By.LINK_TEXT, 'link_text') # (根据连接文本元素列表)
driver.find_element(By.PARTIAL_LINK_TEXT, 'partial_link_text') # (根据链接包含的文本元素列表)
driver.find_element(By.XPATH, 'xpath') # (返回一个包含元素的列表)
理论上这些信息都可实现定位,但好像有时某些信息不能定位,某些信息则可,需要自己多试(也许是我的水平太菜)。针对全选,我尝试的结果是这个有效,对应代码如下:
driver.find_element(By.CLASS_NAME, "checkAll").click() # 勾选全选
再比如高级检索页面中,输入检索条件后,要点击检索按钮。查看代码可知定位之简单:
'''
# 点击检索按钮
WebDriverWait(driver, 100).until(
EC.presence_of_element_located((By.XPATH, "/html/body/div[2]/div[1]/div[1]/div/div[2]/div/div[1]/div[1]/div[2]/div[3]/input"))
).click() # 无/input也可
'''
# 找到检索按钮并单击它,这种方法比上面更简单直接
search_button = driver.find_element(By.CLASS_NAME, "btn-search")
search_button.click()