1. selenium基础

selenium部分可以去看我写的selenium基础部分,由于链接太多了这里就不发出来了。

代理ip:

有时候频繁爬取一些网页。服务器发现你是爬虫后会封掉你的ip地址。这时候我们可以更改代理ip。更改代理ip不同的浏览器有不同的实现方式。这里使用我最常用的Chrome浏览器为例。

from selenium import webdriver
chromeOptions = webdriver.ChromeOptions() # 设置代理
chromeOptions.add_argument("--proxy-server=http://202.20.16.82:10152")
# 一定要注意,=两边不能有空格,不能是这样--proxy-server = http://202.20.16.82:10152
driver = webdriver.Chrome(chrome_options = chromeOptions) # 查看本机ip,查看代理是否起作用
driver.get("http://httpbin.org/ip")
print(driver.page_source) # 退出,清除浏览器缓存
driver.quit()

注意事项:

第一,选择稳定的固定的代理IP。不要选择动态代理IP。我们常用的爬虫IP代理通常都是具有高度保密性质的高匿名动态IP,是通过拨号动态产生的,时效性非常的短,一般都是在3分钟左右。

第二,选择速度较快的代理IP。因为selenium爬虫采用的是浏览器渲染技术,这种浏览器渲染技术速度就本身就很慢。如果选择的代理IP速度较慢,爬取的时间就会进一步增加。

第三,要有足够大的电脑内存。因为chrome占内存较大,在并发度很高的情况下,容易造成浏览器崩溃,也就是程序崩溃。

第四,在程序结束时,调用driver.quit( )清除浏览器缓存。

2. selenium爬虫实例

选案例真的给我整吐了,开始想弄最常用的淘宝,结果一点搜索就要登录,然后就是天猫,点击下一页就需要登录,搞得我就爬了第一页。最后还是京东好,什么都可以。

2.1 初步分析

像京东、淘宝、天猫这些网站都是动态加载,刚打开只会加载几十条数据,当滑动条到达一定位置的时候,才会继续加载。这时候我们可以通过selenium模拟浏览器下拉网页的过程,获取网站全部商品的信息。

browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")

2.2 模拟翻页

在前面,我们如果要爬取查询的每一页的内容,我们只能分析url,找规律,才能跳转到下一页,并获取数据。

现在我们就可以使用xpath定位+selenium点击,来模拟浏览器的翻页行为了。

下拉网页至底部可以发现有一个下一页的按钮,我们只需获取并点击该元素即可实现翻页。

browser.find_element_by_xpath('//a[@class="pn-next" and @onclick]').click()

2.3 获取数据

接下来,我们需要解析每一个网页来获取我们需要的数据,具体包括(可以使用selenium选择元素):

商品 ID:browser.find_elements_by_xpath('//li[@data-sku]'),用于构造链接地址

商品价格:browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[2]/strong/i')

商品名称:browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[3]/a/em')

评论人数:browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[4]/strong')

2.4 代码实现

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import selenium.common.exceptions
import json
import csv
import time class JdSpider():
def open_file(self):
self.fm = input('请输入文件保存格式(txt、json、csv):')
while self.fm!='txt' and self.fm!='json' and self.fm!='csv':
self.fm = input('输入错误,请重新输入文件保存格式(txt、json、csv):')
if self.fm=='txt' :
self.fd = open('Jd.txt','w',encoding='utf-8')
elif self.fm=='json' :
self.fd = open('Jd.json','w',encoding='utf-8')
elif self.fm=='csv' :
self.fd = open('Jd.csv','w',encoding='utf-8',newline='') def open_browser(self):
self.browser = webdriver.Chrome()
self.browser.implicitly_wait(10)
self.wait = WebDriverWait(self.browser,10) def init_variable(self):
self.data = zip()
self.isLast = False def parse_page(self):
try:
skus = self.wait.until(EC.presence_of_all_elements_located((By.XPATH,'//li[@class="gl-item"]')))
skus = [item.get_attribute('data-sku') for item in skus]
links = ['https://item.jd.com/{sku}.html'.format(sku=item) for item in skus]
prices = self.wait.until(EC.presence_of_all_elements_located((By.XPATH,'//div[@class="gl-i-wrap"]/div[2]/strong/i')))
prices = [item.text for item in prices]
names = self.wait.until(EC.presence_of_all_elements_located((By.XPATH,'//div[@class="gl-i-wrap"]/div[3]/a/em')))
names = [item.text for item in names]
comments = self.wait.until(EC.presence_of_all_elements_located((By.XPATH,'//div[@class="gl-i-wrap"]/div[4]/strong')))
comments = [item.text for item in comments]
self.data = zip(links,prices,names,comments)
except selenium.common.exceptions.TimeoutException:
print('parse_page: TimeoutException')
self.parse_page()
except selenium.common.exceptions.StaleElementReferenceException:
print('parse_page: StaleElementReferenceException')
self.browser.refresh() def turn_page(self):
try:
self.wait.until(EC.element_to_be_clickable((By.XPATH,'//a[@class="pn-next"]'))).click()
time.sleep(1)
self.browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")
time.sleep(2)
except selenium.common.exceptions.NoSuchElementException:
self.isLast = True
except selenium.common.exceptions.TimeoutException:
print('turn_page: TimeoutException')
self.turn_page()
except selenium.common.exceptions.StaleElementReferenceException:
print('turn_page: StaleElementReferenceException')
self.browser.refresh() def write_to_file(self):
if self.fm == 'txt':
for item in self.data:
self.fd.write('----------------------------------------\n')
self.fd.write('link:' + str(item[0]) + '\n')
self.fd.write('price:' + str(item[1]) + '\n')
self.fd.write('name:' + str(item[2]) + '\n')
self.fd.write('comment:' + str(item[3]) + '\n')
if self.fm == 'json':
temp = ('link','price','name','comment')
for item in self.data:
json.dump(dict(zip(temp,item)),self.fd,ensure_ascii=False)
if self.fm == 'csv':
writer = csv.writer(self.fd)
for item in self.data:
writer.writerow(item) def close_file(self):
self.fd.close() def close_browser(self):
self.browser.quit() def crawl(self):
self.open_file()
self.open_browser()
self.init_variable()
print('开始爬取')
self.browser.get('https://search.jd.com/Search?keyword=%E7%AC%94%E8%AE%B0%E6%9C%AC&enc=utf-8')
time.sleep(1)
self.browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")
time.sleep(2)
count = 0
while not self.isLast:
count += 1
print('正在爬取第 ' + str(count) + ' 页......')
self.parse_page()
self.write_to_file()
self.turn_page()
self.close_file()
self.close_browser()
print('结束爬取') if __name__ == '__main__':
spider = JdSpider()
spider.crawl()

代码中需要注意的地方:

1.self.fd = open('Jd.csv','w',encoding='utf-8',newline='')

在打开csv文件时,最好加上参数newline='',否则我们写入的文件会出现空行,不利于后续的数据处理。

2.self.browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")

在模拟浏览器向下拖动网页时,由于数据更新不及时,所以经常出现StaleElementReferenceException异常,我们可以在操作中加入time.sleep()给浏览器充足的加载时间,或者就是捕获该异常进行相应的处理了。

3.skus = [item.get_attribute('data-sku') for item in skus]

在selenium中使用xpath语法选取元素时,无法直接获取节点的属性值,而需要使用get_attribute()方法。

4.无头启动浏览器可以加快爬取速度,只需在启动浏览器时设置无头参数即可。

opt = webdriver.chrome.options.Options()
opt.set_headless()
browser = webdriver.Chrome(chrome_options=opt)

爬虫(十一):selenium爬虫的更多相关文章

  1. Python爬虫之selenium爬虫,模拟浏览器爬取天猫信息

    由于工作需要,需要提取到天猫400个指定商品页面中指定的信息,于是有了这个爬虫.这是一个使用 selenium 爬取天猫商品信息的爬虫,虽然功能单一,但是也算是 selenium 爬虫的基本用法了. ...

  2. 爬虫系列---selenium详解

    一 安装 pip install Selenium 二 安装驱动 chrome驱动文件:点击下载chromedriver (yueyu下载) 三 配置chromedrive的路径(仅添加环境变量即可) ...

  3. [Python爬虫]使用Selenium操作浏览器订购火车票

    这个专题主要说的是Python在爬虫方面的应用,包括爬取和处理部分 [Python爬虫]使用Python爬取动态网页-腾讯动漫(Selenium) [Python爬虫]使用Python爬取静态网页-斗 ...

  4. 一起学爬虫——使用selenium和pyquery爬取京东商品列表

    layout: article title: 一起学爬虫--使用selenium和pyquery爬取京东商品列表 mathjax: true --- 今天一起学起使用selenium和pyquery爬 ...

  5. Python 爬虫利器 Selenium 介绍

    Python 爬虫利器 Selenium 介绍 转 https://mp.weixin.qq.com/s/YJGjZkUejEos_yJ1ukp5kw 前面几节,我们学习了用 requests 构造页 ...

  6. Python爬虫之selenium的使用(八)

    Python爬虫之selenium的使用 一.简介 二.安装 三.使用 一.简介 Selenium 是自动化测试工具.它支持各种浏览器,包括 Chrome,Safari,Firefox 等主流界面式浏 ...

  7. python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用

    python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用 一丶单线程+多任务的异步协程 特殊函数 # 如果一个函数的定义被async修饰后,则该函数就是一个特殊的函数 async ...

  8. Python爬虫之selenium高级功能

    Python爬虫之selenium高级功能 原文地址 表单操作 元素拖拽 页面切换 弹窗处理 表单操作 表单里面会有文本框.密码框.下拉框.登陆框等. 这些涉及与页面的交互,比如输入.删除.点击等. ...

  9. Python爬虫之selenium库使用详解

    Python爬虫之selenium库使用详解 本章内容如下: 什么是Selenium selenium基本使用 声明浏览器对象 访问页面 查找元素 多个元素查找 元素交互操作 交互动作 执行JavaS ...

随机推荐

  1. WPF Dispatcher.BeginInvoke子线程更新UI

    在开发WPF应用时出现:”调用线程无法访问此对象,因为另一个线程拥有该对象.“ 是因为UI线程是WPF应用的主线程,若尝试子线程更新UI线程应使用Dispatcher.BeginInvoke()或者I ...

  2. yarn 不要一起用 npm

    yarn 不要一起用 npm 如果一起用,看下lock 的版本一样不,不一样可能会出现问题

  3. npm 基础命令

    npm是一个node包管理和分发工具,已经成为了非官方的发布node模块(包)的标准.有了npm,可以很快的找到特定服务要使用的包,进行下载.安装以及管理已经安装的包.npm 从5.2版开始,增加了 ...

  4. 大型数据库技术实验六 实验6:Mapreduce实例——WordCount

    现有某电商网站用户对商品的收藏数据,记录了用户收藏的商品id以及收藏日期,名为buyer_favorite1. buyer_favorite1包含:买家id,商品id,收藏日期这三个字段,数据以“\t ...

  5. mybatis-plus热部署mapper.xml插件JRebel MybatisPlus extension,报错:java.lang.NullPointerException

    事件 mybatis转mybatis-plus,结果原来的Jrebel for intrllij 不能热部署mapper.xml文件,百度得知得添加新的插件 JRebel MybatisPlus ex ...

  6. TODO:rest和restful接口是什么?

    todo: 参考: http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html https://www.jianshu ...

  7. Spring-Boot-2.0.0-M1版本将默认的数据库连接池从tomcat jdbc pool改为了hikari

    spring-configuration-metadata.json spring-boot-autoconfigure-2.0.0.M7.jar!/META-INF/spring-configura ...

  8. redis string类型 增删改查

    string一.设置 1.设置一个键值对时,如果该键已存在,那么就成了updata (key:value) 例: set name jiang 访问值:get name 2.设置值过期时间:setex ...

  9. 158.Clickjacking点击劫持攻击实现和防御措施

    clickjacking攻击: clickjacking攻击又称为点击劫持攻击,是一种在网页中将恶意代码等隐藏在看似无害的内容(如按钮)之下,并诱使用户点击的手段. clickjacking攻击场景: ...

  10. 洛谷P1147 连续自然数和

    https://www.luogu.org/problem/P1147 #include<bits/stdc++.h> using namespace std; int main(){ i ...