使用 selenium 爬取动态网页内容,并保存到数据库中
一、本章介绍
本章主要的内容是通过使用 selenium 来爬取动态网页的内容,并将内容保存到 MongoDB 数据库中。
本章目的是爬取公共厕所信息,比如厕所地址,名称等,然后将其保存成JSON格式或保存到数据库中。
目标网站:https://ditu.so.com/
二、环境准备
1.selenium
推荐下载版本为 3.14
下载方法:
打开终端,输入
pip install selenium==3.14
2.chromedriver
下载 chromedriver 之前要先查看本机 chrome 版本。
打开chrome,点击右上角三个竖着的点,找到帮助,点击关于Google Chrome。
可以看到本机chrome版本为 115.0.5790.102
打开下载chromedriver网站,找到对应本机chrome的chromedriver版本。
例如我下载的 chromedriver 的版本为 114.0.5735.90 。点击114.0.5735.90/,进入目录找到本机对应的环境下载压缩包。
将下载的 chromedriver 解压后放在 Google Chrome 的文件中,双击 chromedriver.exe ,如果看到 ChromeDriver was started successfully ,则证明成功,并且要将 chromedriver 添加系统环境变量。
全都下载并且配置好之后,测试一下是否能使用chromedriver。
from selenium import webdriver
import time
#建议使用Chrome Webdriver
#Chrome Web Driver,预设有介面
driver = webdriver.Chrome()
#访问百度网站,基础用法
driver.get("http://www.baidu.com")
#关闭浏览器,非必要,但建议要做
time.sleep(15)
driver.quit()
如果 Chrome 打开并且跳转至百度界面,则证明我们的 chromedriver 配置成功。
3.MongoDB
MongoDB 数据库要下载两个部分,分别为 MongoDB 主程序和 MongoDB compass 数据库的图形化管理系统。
我已经将程序上传百度云盘。
MongoDB 主程序,提取码:ccit
MongoDB compass,提取码:ccit
安装 MongoDB 主程序:
双击运行程序,一直单击下一步默认设置,到Choose Setup Type,选择custom,然后一直单击下一步默认设置,到Install MongoDB Compass,取消勾选,等待安装完成。
安装 MongoDB compass:
双击运行程序,等待加载完成,一直单击Next,跳过教程,之后单击Start Using Compass,启动。Connect To Host部分,全都采用预设值,单击Connect。看到三个数据库(admin,config,local)则配置成功。
设置 MongoDB 到我们系统的环境变量。
三、项目实现
我们先打开目标网站,思考怎么样查找我们需要的内容。
我们需要找到附近公共厕所的信息,就需要在网站的搜索框中搜索公共厕所,然后单击搜索按钮。
1.使用 selenium 打开目标网站
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://ditu.so.com/")
2.找到输入框,将关键词输入
content_element = driver.find_element_by_class_name('react-autosuggest__input').send_keys("what want to find!")
使用 selenium 的 driver.find_element_by_class_name 方法定位标签元素。那么怎么得到目标的标签呢?
使用 selenium 的 driver.send_keys 方法将需要查找的内容输入搜索框。
3.找到搜索按钮,在输入关键词后开始搜索
from selenium.webdriver import ActionChains
search_element = driver.find_element_by_class_name('search')
time.sleep(2)
# 单击搜索按钮
ActionChains(driver).click(on_element=search_element).pause(0.1).perform()
使用 selenium 的 driver.find_element_by_class_name 方法查找到搜索按钮位置。
使用 selenium 的 ActionChains(driver).click()…perform() 单击搜索按钮实现搜索效果。
4.找到想要查找的信息
搜索到我们想要的信息之后我们就要定位信息,以便我们将其保存。
items = []
print('*' * 50)
toliet_list = driver.find_elements_by_class_name("ZhyAZMuVKiND1Z0fU6X6")
for content in toliet_list:
# 公厕名称
toliet_find = content.find_element_by_class_name("QqYxXPBfGK3P4VZZGH1x").text
# 公厕地址
address_find = content.find_element_by_class_name("Koobo8bUnpuiG16tPSZh").text
# 公厕离你的距离
distance_find = content.find_element_by_tag_name("span").text
print("公厕名称:{}".format(toliet_find))
print("公厕地点:{}".format(address_find))
print("离您的距离:{}".format(distance_find))
print('*' * 50)
time.sleep(2)
item={
"公厕名称": toliet_find,
"公厕地点": address_find,
"公厕离您的距离": distance_find
}
items.append(item)
我们要的信息是 公厕名称, 公厕地址, 公厕离你的距离,找到之后将他们打印出来。
注:公厕离你的距离 有时不会显示出来原因可能是距离太远了,如果不显示,就把显示距离的部分注释掉。
5. 保存数据
以JSON数据格式保存:
try:
with open('./toliet.json', mode='w+', encoding='utf-8') as f:
f.write(json.dumps(items, ensure_ascii=False, indent=2))
except Exception as e:
print(e)
我们得到想要的信息之后,将其保存在 toliet.json。
保存到 MongoDB 数据库中:
client = MongoClient()
db = client['toliet']
collection = db['nearby_toliet']
collection.insert_one({'公厕名称': toliet_find,
'公厕地点': address_find,
'公厕离您的距离': distance_find})
注:保存到数据库的时候需要先启动数据库不然会报错。
代码汇总:
from selenium import webdriver
import time
from selenium.webdriver import ActionChains
from selenium.webdriver import ChromeOptions
import json
from pymongo import MongoClient
# 爬取动态网页,初始化设置
# 使用Chrome Webdriver
# 带一个–ignore-certificate-errors的参数,忽略掉那些证书错误
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("detach", True)
chrome_options.add_argument('---ignore-certificate-errors-spki-list')
chrome_options.add_argument('--ignore-ssl-errors')
chrome_options.add_argument('--ignore-ssl-error')
chrome_options.add_argument('log-level=2')
# 反反爬虫的手段 :>
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])
driver = webdriver.Chrome(options=chrome_options)
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
})
def dynamic_operations(input_content):
# 访问360地图
driver.get("https://ditu.so.com/")
# 定义将搜索的关键词
# 找到输入框,将关键词输入
content_element = driver.find_element_by_class_name('react-autosuggest__input').send_keys(input_content)
time.sleep(2)
# 找到搜索按钮,在输入关键词后开始搜索
search_element = driver.find_element_by_class_name('search')
time.sleep(2)
# 单击搜索按钮
ActionChains(driver).click(on_element=search_element).pause(0.1).perform()
# 关闭浏览器。
# time.sleep(15)
# driver.quit()
# 开始爬取需要的资料
def parse_toliet(input_content):
dynamic_operations(input_content)
client = MongoClient()
db = client['toliet']
collection = db['nearby_toliet']
items = []
print('*' * 50)
toliet_list = driver.find_elements_by_class_name("ZhyAZMuVKiND1Z0fU6X6")
for content in toliet_list:
# 公厕名称
toliet_find = content.find_element_by_class_name("Pf3UqpeKMUTg1rfFBdBp").text
# 公厕地址
address_find = content.find_element_by_class_name("Koobo8bUnpuiG16tPSZh").text
# 公厕离你的距离
# distance_find = content.find_element_by_tag_name("span").text
print("公厕名称:{}".format(toliet_find))
print("公厕地点:{}".format(address_find))
# print("离您的距离:{}".format(distance_find))
print('*' * 50)
time.sleep(2)
item={
"公厕名称": toliet_find,
"公厕地点": address_find,
# "公厕离您的距离": distance_find
}
items.append(item)
collection.insert_one({'公厕名称': toliet_find,
'公厕地点': address_find})
save_data(items)
# time.sleep(15)
# 关闭浏览器
# driver.quit()
def save_data(items):
try:
with open('./toliet.json', mode='w+', encoding='utf-8') as f:
f.write(json.dumps(items, ensure_ascii=False, indent=2))
except Exception as e:
print(e)
if __name__ == "__main__":
input_content = input("请输入要搜索的内容:")
parse_toliet(input_content)
结果展示:
toliet.json文件:
控制台:
MongoDB 数据库: