一,准备工作
1.安装Selenium库
Selenium通过使用 WebDriver 支持市场上所有主流浏览器的自动化。 Webdriver 是一个 API 和协议,它定义了一个语言中立的接口,用于控制 web 浏览器的行为。 每个浏览器都有一个特定的 WebDriver 实现,称为驱动程序。 驱动程序是负责委派给浏览器的组件,并处理与 Selenium 和浏览器之间的通信。
如果使用的是Pycharm软件,则可以直接Python解释器中直接添加,如果无法添加则可通过命令添加:打开DOS命令窗口输入:
pip install selenium
如再次无法安装则用国内镜像资源网站添加:
pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple
成功后重启Pycharm,软件会自动扫描本机原装的库。
2.安装scrapy库
步骤与安装Selenium一样,直接放代码:
pip install scrapy
pip install scrapy-i https://pypi.tuna.tsinghua.edu.cn/simple
3.Chorme浏览器安装
由于需要用Chorme浏览器启动,要求Chorme版本和ChormeDriver版本严格一致,故在安装chorme和chormedriver的时候一定要版本一致,我直接把下载网站(99.0.4844.51版本)放在下面,选择有相同版本的chorme和chormedriver进行下载:
Chorme:
Chorme浏览器(99.0.4844.51)
https://downzen.com/en/windows/google-chrome/download/990484451/
ChormeDriver:
ChormeDriver(99.0.4844.51)
https://registry.npmmirror.com/binary.html?path=chromedriver/99.0.4844.51/
二,相关代码
1.所用到的包
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import pickle
import time
2.函数体说明
本次代码我把主要的功能用两个函数实现,方便读者理解代码。
spider函数是一个网络爬虫的部分实现,如下:
def spider(url, keyword): # 两个参数:url即为京东网站,keyword即为爬取的商品名称
driver = webdriver.Chrome(executable_path=r"ChormeDriver安装路径") #启动浏览器
try:
driver.get(url) # 将网址传递给driver
get_goods(driver, keyword) # 给get_goods传入参数,看下段get_goods代码介绍
finally:
driver.quit() # 清理driver资源
finally:只要 try 里面代码运行结束(或者因异常结束)浏览器都会释放资源关闭。
gets_goods函数说明
input_tag = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, 'key'))
)
input_tag.send_keys(keyword)
input_tag.send_keys(Keys.ENTER) # 在搜索框自动输入keyword
WebDriverWait第二个参数为等待时间,浏览器会等待10秒,直到等待具有特定ID(京东页面在这里是‘key’)的元素出现在页面上。如果元素在指定的时间内(这里是10秒)变得可用,则代码会向该元素发送文本(keyword变量中的值)和回车键(通过Key.ENTER实现)。
WebDriverWait(driver, 20).until(
EC.presence_of_all_elements_located((By.CLASS_NAME, 'gl-item'))
)
goods = driver.find_elements_by_class_name('gl-item')
WebDriverWait结合EC.presence_of_all_elements_located来等待页面上所有具有特定类名('gl-item')的元素变得可用。一旦这些元素被检测到存在于DOM中,你就使用find_elements_by_class_name来获取这些元素的列表。
for page in range(1, 10): # 切换到当前页面(对于第一页,可自行修改)
for good in goods: # 遍历当前页面的商品
detail_url = good.find_element_by_tag_name('a').get_attribute('href')
p_name = good.find_element_by_css_selector('.p-name em').text.replace('\n', '')
price_element = good.find_element_by_css_selector('.p-price i')
price = price_element.text if price_element.text else 'N/A'
p_commit = good.find_element_by_css_selector('.p-commit a').text
msg = f"""
商品 : {p_name}
链接 : {detail_url}
价钱 : {price}
评论 : {p_commit}
"""
print(msg)
detail_ur: 对于每个商品元素(good),找到其内部的第一个标签,并获取其href属性。
p_name: 使用CSS选择器找到商品名称。这里商品名称被包裹在具有类名'p-name'的元素内的标签中。然后,它获取该元素的文本内容并移除其中的换行符。
price_element:使用CSS选择器找到价格元素。这里假设价格被包裹在具有类名'p-price'的元素内的标签中。
price:获取价格元素的文本内容。如果文本为空(可能没有找到价格或价格为空),则设置价格为'N/A'。
p_commit: 使用CSS选择器找到评论数量或链接。这里京东评论信息被包裹在具有类名'p-commit'的元素内的标签中。然后,它获取该元素的文本内容。
msg: 使用f-string(格式化字符串文字)创建一个包含商品信息的字符串。这个字符串包含了商品名称、链接、价格和评论。
try:
next_page_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, '下一页'))
)
next_page_button.click() # 找到的“下一页”按钮的点击
time.sleep(1) # 等待页面加载
get_goods(driver, keyword)
except TimeoutException:
pass # 没有下一页按钮,退出递归
next_page_button:
- 这里使用了Selenium的WebDriverWait对象来等待某个条件成立。具体来说,它等待直到页面上出现一个可以点击的元素,该元素的链接文本包含“下一页”。
- EC.element_to_be_clickable是一个期望条件(expected condition),它表示元素需要是可见的并且是可点击的。
- (By.PARTIAL_LINK_TEXT, '下一页')是一个定位器(locator),它指定了要查找的元素应该具有包含“下一页”的链接文本。
- 如果在10秒内找到了这样的元素,WebDriverWait将返回该元素,并将其存储在next_page_button变量中。
time.sleep:代码使程序暂停1秒。这是一个简单的等待机制,用于确保页面有足够的时间加载新的内容。但是因为页面加载时间可能因各种因素而异,这种方法并不总是可靠或高效的。
get_goods:代码调用了一个名为get_goods的函数(该函数在您提供的代码段中没有定义,但我可以推测它是用于从当前页面获取商品信息的)。它传递了driver(WebDriver对象)和keyword(可能是用于搜索商品的关键字)作为参数。
except TimeoutException:
try代码块中出现TimeoutException(如果在10秒内没有找到可点击的“下一页”按钮)则程序将跳转到这个except块。 pass是一个空操作语句,它在这里表示当发生TimeoutException时,程序什么都不做(即不执行任何操作)。
三,完整代码
下面是整个项目的完整代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import time
def get_goods(driver, keyword):
try:
input_tag = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, 'key'))
)
input_tag.send_keys(keyword)
input_tag.send_keys(Keys.ENTER)
# 京东会弹出请求登录
WebDriverWait(driver, 20).until(
EC.presence_of_all_elements_located((By.CLASS_NAME, 'gl-item'))
)
goods = driver.find_elements_by_class_name('gl-item')
for page in range(1, 10):
for good in goods:
detail_url = good.find_element_by_tag_name('a').get_attribute('href')
p_name = good.find_element_by_css_selector('.p-name em').text.replace('\n', '')
price_element = good.find_element_by_css_selector('.p-price i')
price = price_element.text if price_element.text else 'N/A'
p_commit = good.find_element_by_css_selector('.p-commit a').text
msg = f"""
商品 : {p_name}
链接 : {detail_url}
价钱 : {price}
评论 : {p_commit}
"""
print(msg)
try:
next_page_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, '下一页'))
)
next_page_button.click()
time.sleep(1) # 等待页面加载
get_goods(driver, keyword)
except TimeoutException:
pass # 没有下一页按钮,退出递归
except Exception as error:
print(f"发生错误: {error}")
def spider(url, keyword):
driver = webdriver.Chrome(executable_path=r"C:\Users\ASUS\Desktop\chromedriver.exe")
try:
driver.get(url)
get_goods(driver, keyword)
finally:
driver.quit() # 清理driver资源
if __name__ == '__main__':
url = 'https://www.jd.com/'
keyword = '输入商品名称'
spider(url, keyword)
四,关于京东爬取时弹出登录页面
WebDriverWait(driver, 20).until(
EC.presence_of_all_elements_located((By.CLASS_NAME, 'gl-item'))
)
这里设置了在登录页面停留时间为20秒,超时浏览器将释放资源,可自行修改停留时间。
关于实现京东的自动登录,我尝试通过使用用户cookies实现目的,但最后还是失败了,以下是我的部分关于自动登录的代码,供参考借鉴
def load_cookies(driver, cookie_path):
"""加载cookies到driver"""
if os.path.exists(cookie_path):
with open(cookie_path, 'rb') as f:
cookies = pickle.load(f)
for cookie in cookies:
driver.add_cookie(cookie)
class CookieLogin():
def __init__(self):
self.drive = webdriver.Chrome(executable_path=r"C:\Users\ASUS\Desktop\chromedriver.exe")
self.url = 'https://passport.jd.com/new/login.aspx?/'
# 先手动登录,让程序获取到cookie,保存下来
def getcookie(self):
# 首先直接访问登录的页面 passport.jd.com
self.drive.get(self.url)
# 扫码登录
# 登录之后的页面会跳转到这里,让浏览器等待,直到url完全匹配
url = 'https://www.jd.com/'
WebDriverWait(self.drive, 30).until(EC.url_to_be(url))
# # 登录之后停2秒
# time.sleep(2)
版权归原作者 理想蛙人 所有, 如有侵权,请联系我们删除。