2021/5/18爬虫第十三次课(行为链、无界面模式、selenium爬取数据案例)

一、(鼠标)行为链

有时候在页面中的操作可能要有很多步,那么这时候可以使用鼠标行为链类ActionChains来完成。比如现在要将鼠标移动到某个元素上并执行点击事件

actions = ActionChains(driver)
actions.move_to_element(inputTag)
actions.send_keys_to_element(inputTag,'python')
actions.move_to_element(submitTag)
actions.context_click()
actions.click(submitTag)
actions.perform()

还有更多的鼠标相关的操作
• click_and_hold(element):点击但不松开鼠标。
• context_click(element):右键点击。
• double_click(element):双击。
• 更多方法请参考:http://selenium-python.readthedocs.io/api.html

具体使用:

from selenium import webdriver
from selenium.webdriver import ActionChains
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
time.sleep(1)
# 定位输入框
inputTag = driver.find_element_by_id('kw')

# 定位百度一下的按钮
buttonTag = driver.find_element_by_id('su')

#鼠标行为链开始
# 实例化对象
actions = ActionChains(driver)

# 往输入框里面输入内容
actions.send_keys_to_element(inputTag,'浩哥')

time.sleep(1)
# 普通点击行为不要在鼠标行为链里面出现  buttonTag.click()
#点击行为
actions.move_to_element(buttonTag)
actions.click()

# 提交行为链
actions.perform()
#鼠标行为链结束

'''
1 千万不要忘记提交鼠标行为链
actions.perform()
2 需要注意鼠标行为链里面的点击操作 
'''


二、selenium设置无界面模式(模板)

# 创建chrome设置对象
options = webdriver.ChromeOptions()
# 设置无界面功能  --headless 浏览器无界面 --xxxx 
options.add_argument('--headless')
driver = webdriver.Chrome(options=options)
driver.get('https://maoyan.com/board/4')

三、selenium爬取数据

将使用到的一些方法或属性

drvier.page_source 获取html结构的源码
# selenium提取数据的方式,是以页面最终渲染以后,以前端页面为基准的,和响应内容没有什么关系
drvier.find()  在html结构中查找某个字符串是否存在 
drvier.get_attribute('src') 获取节点的属性值 
drvier.text 获取节点的文本内容 (子子孙孙)

具体使用:

from selenium import webdriver
import time
# options=webdriver.ChromeOptions()
# options.add_argument('--headless')
#options=options
driver = webdriver.Chrome()
# driver.get('https://www.baidu.com/')
# time.sleep(1)
# # driver.page_source #获取检查的字符串格式
# html = driver.page_source
# print(type(html))


# find()  在html结构中查找某个字符串是否存在
# 数字就证明存在没有什么规律;如果不存在会返回 -1
# print(driver.page_source.find('kw1212313213123132'))


driver.get('https://maoyan.com/board/4')
time.sleep(1)

img_tag = driver.find_element_by_xpath('//*[@id="app"]/div/div/div[1]/dl/dd[1]/a/img[2]')
print(img_tag.get_attribute('src'))

四、案例

4.1selenium获取猫眼电影top100电影信息

问题:使用selenium获取猫眼电影top100电影信息 电影排名 电影名称 主演 上映时间 评分

分析页面结构 选择合适的技术点
1>明确目标的url https://maoyan.com/board/4
2>我们先搞定一页的电影数据 再去搞定其它页的
3>通过分析 数据都是在dl标签里面 dl标签里面每一个dd标签它就是一部电影
细节:
1》翻页的处理

  • 当我们点击到最后一页的时候 发现下一页的按钮没有了 就可以判断是最后一页了

2》报错的处理

代码:

from selenium import webdriver
import csv

# # 创建chrome设置对象 程序没有问题在去设置 无界面模式
# options = webdriver.ChromeOptions()
# # 设置无界面功能  --headless 浏览器无界面  --xxxx
# options.add_argument('--headless')
# #selenium获取猫眼电影top100电影信息
driver = webdriver.Chrome()
driver.get('https://maoyan.com/board/4')


def get_one_page():
    # 找到这一页的dd标签 千万不要忘记写dd
    dd_lst = driver.find_elements_by_xpath('//*[@id="app"]/div/div/div[1]/dl/dd')
    single_list = []
    for dd in dd_lst:
        # text属性 获取当前dd节点的子子孙孙的文本内容
        # 视情况而分析 验证我们打印的内容有什么规律吗?如果有 就进一步操作
        # print(dd.text)   #str类型   要测试其结果是啥
        # print('*'*80)
        one_film_info_lst = dd.text.split('\n')
        item = {}
        try:
            item['rank'] = one_film_info_lst[0].strip()
            item['name'] = one_film_info_lst[1].strip()
            item['actor'] = one_film_info_lst[2].strip()
            item['time'] = one_film_info_lst[3].strip()
            item['score'] = one_film_info_lst[4].strip()
        except:
            pass
        single_list.append(item)
        print(item)

    return single_list


all_list = []
while True:

    single_list = get_one_page()

    # if 不是最后一页:
    #     driver.find_element_by_link_text('下一页').click()
    # else:
    #     driver.quit()
    #     break

    all_list += single_list
    try:
        # 找不到最后一页 就会抛出异常 此时就证明是最后一页了
        driver.find_element_by_link_text('下一页').click()
    except Exception as e:
        driver.quit()
        break

with open('maoyetop100.csv', 'w', encoding='utf-8', newline='') as file_obj:
    dictwriter = csv.DictWriter(file_obj, fieldnames=['rank', 'name', 'actor', 'time', 'score'])
    dictwriter.writeheader()
    dictwriter.writerows(all_list)

4.2selenium爬取京东某商品数据

分析页面结构 选择合适的技术点
1>我们发现 所有的数据都是在一个ul标签 ul标签下面每一个li标签对应的就是一本书。
2>我们拖动 拖动条(滚轮)的时候 页面又加载了数据
代码中 当我们进入这个页面的时候,把这个拖动条拖动一下,拖到最下面,然后等它加载一会儿,等页面元素加载完了之后,我们再去抓取
#每页 上来先加载30个 当我们进行拖动的时候 它又会加载30个 也就是每页其实是60个数据
如何拖动 拖动条?(我们会用到一个 加载js的方法)

细节:
1》翻页的处理

  • 当我们点击到最后一页的时候 发现下一页的按钮还有 要用find()方法

2》如何拖动 拖动条

3》报错的处理

代码:


from selenium import webdriver
import time
class JdSpider():
    def __init__(self):
        # 设置无界面
        self.options = webdriver.ChromeOptions()
        # 设置无界面功能  --headless 浏览器无界面  --xxxx
        self.options.add_argument('--headless')
        self.driver = webdriver.Chrome(options=self.options)
        self.driver.get('https://www.jd.com/')
        # 定位输入框和按钮
        self.driver.find_element_by_xpath('//*[@id="key"]').send_keys('爬虫书')
        time.sleep(1)
        self.driver.find_element_by_xpath('//*[@id="search"]/div/div[2]/button').click()
        time.sleep(1)


    def pares_html(self):

        # 进入这个页面的时候,把这个拖动条拖动一下,拖到最下面
        # 0 是从去起始位置开始  document.body.scrollHeight 整个窗口的高度  模板!
        self.driver.execute_script(
            'window.scrollTo(0,document.body.scrollHeight)'
        )

        time.sleep(2)

        # 提取数据 千万不要忘记写li
        li_lst = self.driver.find_elements_by_xpath('//*[@id="J_goodsList"]/ul/li')
        for li in li_lst:
            # print(li.text)
            # print('*'*50)
            try:
                item = {}
                item['price'] = li.find_element_by_xpath('.//div[@class="p-price"]/strong').text.strip()
                item['name'] = li.find_element_by_xpath('.//div[@class="p-name"]/a/em').text.strip()
                item['commit'] = li.find_element_by_xpath('.//div[@class="p-commit"]/strong').text.strip()
                item['shop'] = li.find_element_by_xpath('.//div[@class="p-shopnum"]/a').text.strip()
                print(item)
            except Exception as e:
                print(e)


    def main(self):
        while True:
            self.pares_html()
            #
            if self.driver.page_source.find('pn-next disable') == -1:
                self.driver.find_element_by_xpath('//*[@id="J_bottomPage"]/span[1]/a[9]').click()
                time.sleep(1)
            else:
                self.driver.quit()
                break



if __name__ == '__main__':
    spider = JdSpider()
    spider.main()

总结:
一些细节:

  • 拖动条的处理
  • 无界面模式
  • 翻页灵活处理(2种)
  • 报错的解决(指爬取的数据的处理)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笔记本IT

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值