0


[Python 爬虫] Selenium爬取电影《749局》豆瓣热评

版本前瞻:
为防止因为版本不同导致各位遇到奇奇怪怪的错误,特将版本列此,以供参考

  1. Python=3.9 selenium=4.9.1 MongoDB v4.2.24

文章目录

1.环境准备

具体Selenium环境配置请看我的上一篇博客
[Python 爬虫] Selenium及Miniconda3安装

2.确定目标网页及数据范围

通过Selenium自动化测试框架控制浏览器行为
从豆瓣首页打开至电影 749局 短评-热评-全部 并对所有评论进行爬取749局 短评-热评-全部
开始页面
最终页面

3.检查网站的使用条款和 robots.txt (君子协议)

  • 首先仔细查看目标网站的使用条款和隐私政策。有些网站明确禁止爬虫访问,违反规定可能会导致法律问题。
  • 其次查看 robots.txt(不讲武德的直接看下一步)在这里插入图片描述

1.对通用爬虫的限制

  • 禁止爬取的路径包括:/subject_search、/amazon_search、fsearch、fgroup/search、fevent/search、fcelebrities/search、/location/drama/search、fforum/、fnew_subject、fservice/iframe、fj、flink2/、frecommend/、/doubanapp/card、/update/topic/、fsharef、/people//collect、/people//wish、/people//all。
  • 允许爬取的文件为fads.txt。*
  • 提供了两个网站地图地址:https://fwww.douban.com/sitemap_index.xml和https://fwww.douban.com/sitemap_updated_index.xml。*
  • 建议通用爬虫抓取间隔为 5 秒(Crawl-delay: 5)。

2.对豌豆荚爬虫的限制

  • 禁止豌豆荚爬虫(Wandoujia Spider)爬取任何以f开头的路径。

3.对谷歌广告爬虫的限制

  • 禁止谷歌广告爬虫(Mediapartners-Google)爬取/subject_search、/amazon_search、/search、fgroup/search、fevent/search、fcelebrities/search、/location/drama/search、fj路径。

4.代码实现

①.创建构造方法
  1. import time # 用于控制浏览器加载时间 防止爬取速度过快出现异常from random import randint
  2. from pymongo import MongoClient # 使用mongoDB进行数据存储from selenium import webdriver
  3. from selenium.webdriver.common.by import By
  4. from selenium.webdriver.support.ui import WebDriverWait
  5. from selenium.webdriver.support import expected_conditions as EC
  6. # By类用于指定在网页中定位元素的方式# WebDriverWait 类用于等待特定条件的出现# expected_conditions 模块提供了一系列预定义的条件,用于在 WebDriverWait 中等待特定的网页状态或元素状态classDb_Movie749():
  7. client = MongoClient('localhost',27017)
  8. collection = client['py_spider']['Db_749commends']def__init__(self):# 创建浏览器配置对象
  9. self.chrome_options = webdriver.ChromeOptions()# 页面全屏打开
  10. self.chrome_options.add_argument("--start-maximized")
  11. self.prefs ={# 此设置针对的是由管理员或策略管理的内容中的弹出窗口。同样设置为0也是禁止显示弹出窗口"profile.managed_default_content_settings.popups":0,# 阻止所有图像自动加载 加快页面打开速度"profile.managed_default_content_settings.images":2,}
  12. self.chrome_options.add_experimental_option('prefs', self.prefs)# 创建驱动器对象
  13. self.browser = webdriver.Chrome(options=self.chrome_options)
②.使用selenium打开目标页面

Selenium框架元素定位方法
在定位元素时,需要借助selenium框架提供的定位工具来进行元素定位。元素定位工具导入路径如下:
from selenium.webdriver.common.by import By
为了能够点击某个按钮,此时我们就需要准确无误的定位到需要的元素。元素定位主要分为以下两种:
● 单个节点(返回是一个对象)
○ find_element(By.ID, ‘定位规则’)
通过元素唯一的ID属性定位单个元素
○ find_element(By.NAME, ‘定位规则’)
依元素NAME属性值定位单个元素
○ find_element(By.XPATH, ‘定位规则’)
借助强大的XPATH表达式定位单个元素,可依据元素层次结构、属性等多条件精准定位
○ find_element(By.LINK_TEXT, ‘定位规则’)
根据链接完整文本内容定位单个链接元素,要求文本完全匹配。
○ find_element(By.PARTIAL_LINK_TEXT, ‘定位规则’)
按链接文本部分内容定位单个链接元素,适用于已知部分文本的情况。
○ find_element(By.TAG_NAME, ‘定位规则’)
基于元素标签名定位单个元素,但可能因同名标签较多需进一步筛选。
○ find_element(By.CLASS_NAME, ‘定位规则’)
通过元素类名定位单个元素,注意类名可能不唯一,需确保能准确找到目标。
○ find_element(By.CSS_SELECTOR, ‘定位规则’)
运用CSS选择器定位单个元素,能结合多种条件灵活定位元素。
● 多个节点(返回是一个列表)
○ find_elements(By.ID, ‘定位规则’)
○ find_elements(By.NAME, ‘定位规则’)
○ find_elements(By.XPATH, ‘定位规则’)
○ find_elements(By.LINK_TEXT, ‘定位规则’)
○ find_elements(By.PARTIAL_LINK_TEXT, ‘定位规则’)
○ find_elements(By.TAG_NAME, ‘定位规则’)
○ find_elements(By.CLASS_NAME, ‘定位规则’)
○ find_elements(By.CSS_SELECTOR, ‘定位规则’)

注意!!!
在 Selenium 4.0 版本开始,对元素定位方法进行了一些调整和简化,使用find_element和find_elements系列方法来进行元素定位!!!
在这里插入图片描述

流程如下:

在这里插入图片描述
1、通过 F12 进行元素定位找到搜索框对应的页面标签输入 749局
在这里插入图片描述

  1. defTargetWeb(self):# 打开豆瓣电影首页
  2. self.browser.get('https://movie.douban.com/')# 设置等待条件,等待搜索输入框元素可见,最长等待10
  3. wait = WebDriverWait(self.browser,10)
  4. ele_input = wait.until(EC.visibility_of_element_located((By.ID,"inp-query")))# 在搜索输入框中输入电影名称"749局"
  5. ele_input.send_keys("749局")

2、找到 “搜索” 的页面标签 selenium通过 By.XPATH 定位进行对浏览器的操作
在这里插入图片描述

  1. # 设置等待条件,等待搜索按钮元素可见,最长等待10秒
  2. ele_button = wait.until(EC.visibility_of_element_located((By.XPATH,"//div[@class='inp-btn']/input")))# 点击搜索按钮
  3. ele_button.click()
  4. time.sleep(2)

3、通过超链接文本定位电影链接元素
在这里插入图片描述

  1. # 设置等待条件,通过超链接文本定位电影链接元素,最长等待10秒
  2. movie_button = wait.until(EC.visibility_of_element_located((By.LINK_TEXT,'749局 (2024)')))# 点击电影链接
  3. movie_button.click()

4、进入该页面后需要控制浏览器向下滑动!!! 找到 目标位置****“749的短评-热门”

如果不控制浏览器向下滑动就通过selenium对 目标位置 进行元素定位是无法进行的

在这里插入图片描述
在这里插入图片描述

  1. # 执行JavaScript代码向下滚动页面1500像素
  2. js_code =f'window.scrollTo(0, 1500);'
  3. self.browser.execute_script(js_code)# 随机等待12秒,模拟用户操作的随机性
  4. time.sleep(randint(1,2))
③.开始爬取

1、进入到目标页面,开始爬取,用户及对应的评论,使用字典进行储存

  1. defparse_comments(self):
  2. comments_info = self.browser.find_elements(By.XPATH,"//div[@id='comments']/div[@class='comment-item ']")for comment in comments_info:
  3. name = comment.find_element(By.XPATH,".//div[@class='comment']//span[@class='comment-info']/a").text
  4. comment = comment.find_element(By.XPATH,'.//p/span[@class="short"]').text
  5. item ={'name': name,'comment': comment
  6. }

2、使用MongoDB进行数据存储

  1. # 数据存储defsave_info(self,item):
  2. self.collection.insert_one(item)

3、下滑至页面底部通过元素定位到 “后页” 当前页面爬取完毕后进行翻页,数据量:一共五页 一页二十条

这里同样要注意先要先下滑到页面显示出 “后页” 后才能对其进行定位

在这里插入图片描述

  1. # 控制页面下滑defdrop_down(self):for num inrange(1,6):
  2. js_code =f'window.scrollBy(0, {num *500});'
  3. self.browser.execute_script(js_code)
  4. time.sleep(randint(1,2))# 翻页defnext_page(self):try:
  5. next_button = self.browser.find_element(By.XPATH,'//div[@id="paginator"]/a[@class="next"]')
  6. next_button.click()
  7. self.parse_comments()except Exception as e:print('最后一页:',e)
  8. self.browser.quit()# 翻至最后一页关闭页面

4、最后通过主函数控制代码逻辑

  1. defmain(self):
  2. self.TargetWeb()
  3. self.parse_comments()

4.完整代码及爬取结果展示

  1. import time
  2. from random import randint
  3. from pymongo import MongoClient
  4. from selenium import webdriver
  5. from selenium.webdriver.common.by import By
  6. from selenium.webdriver.support.ui import WebDriverWait
  7. from selenium.webdriver.support import expected_conditions as EC
  8. classDb_Movie749():
  9. client = MongoClient('localhost',27017)
  10. collection = client['py_spider']['Db_749commends']def__init__(self):# 创建浏览器配置对象
  11. self.chrome_options = webdriver.ChromeOptions()# 页面全屏打开
  12. self.chrome_options.add_argument("--start-maximized")
  13. self.prefs ={# 此设置针对的是由管理员或策略管理的内容中的弹出窗口。同样设置为0也是禁止显示弹出窗口"profile.managed_default_content_settings.popups":0,# 阻止所有图像自动加载"profile.managed_default_content_settings.images":2,}
  14. self.chrome_options.add_experimental_option('prefs', self.prefs)# 创建驱动器对象
  15. self.browser = webdriver.Chrome(options=self.chrome_options)# 请求页面并进行搜索 为确保要定位的页面元素已经加载出来通过创建wait对象等待defTargetWeb(self):try:
  16. self.browser.get('https://movie.douban.com/')
  17. wait = WebDriverWait(self.browser,10)
  18. ele_input = wait.until(EC.presence_of_element_located((By.ID,"inp-query")))
  19. ele_input.send_keys("749局")
  20. ele_button = wait.until(EC.presence_of_element_located((By.XPATH,"//div[@class='inp-btn']/input")))
  21. ele_button.click()
  22. time.sleep(2)# 通过超链接文本进行定位
  23. movie_button = wait.until(EC.presence_of_element_located((By.LINK_TEXT,'749局 (2024)')))# 通过xpath定位# movie_button = wait.until(EC.presence_of_element_located((By.XPATH,"//a[@href='https://movie.douban.com/subject/26747919/']")))
  24. movie_button.click()# 向下翻页
  25. js_code =f'window.scrollBy(0, 1500);'
  26. self.browser.execute_script(js_code)
  27. time.sleep(randint(1,2))# 对短评进行定位
  28. comments_button = wait.until(EC.presence_of_element_located((By.LINK_TEXT,'热门')))
  29. comments_button.click()# 进行休眠
  30. time.sleep(randint(1,3))except Exception as e:print(f"在请求搜索过程中出现错误: {e}")defdrop_down(self):for num inrange(1,6):
  31. js_code =f'window.scrollBy(0, {num *500});'
  32. self.browser.execute_script(js_code)
  33. time.sleep(randint(1,2))# 数据提取defparse_comments(self):
  34. self.drop_down()
  35. comments_info = self.browser.find_elements(By.XPATH,"//div[@id='comments']/div[@class='comment-item ']")for comment in comments_info:
  36. name = comment.find_element(By.XPATH,".//div[@class='comment']//span[@class='comment-info']/a").text
  37. comment = comment.find_element(By.XPATH,'.//p/span[@class="short"]').text
  38. item ={'name': name,'comment': comment
  39. }
  40. self.save_info(item)print(item)
  41. self.next_page()# 数据存储defsave_info(self,item):
  42. self.collection.insert_one(item)# 翻页defnext_page(self):try:
  43. next_button = self.browser.find_element(By.XPATH,'//div[@id="paginator"]/a[@class="next"]')
  44. next_button.click()
  45. self.parse_comments()except Exception as e:print('最后一页:',e)
  46. self.browser.quit()defmain(self):
  47. self.TargetWeb()
  48. self.parse_comments()if __name__ =='__main__':
  49. db_Movie = Db_Movie749()
  50. db_Movie.main()

在这里插入图片描述

5.异常情况

当访问次数过于频繁,当前IP将不能直接访问第二页以后的评论需要登录才能正常访问,但是由于selenium添加cookie的方法相当鸡肋,无法满足添加所需的cookie信息访问网页以绕过登录,所以如果出现异常情况,通常需要等待一段时间或者可以通过添加代理的方式进行爬取
在这里插入图片描述

标签: python 爬虫 selenium

本文转载自: https://blog.csdn.net/weixin_62274638/article/details/143751097
版权归原作者 小白要努力变强. 所有, 如有侵权,请联系我们删除。

“[Python 爬虫] Selenium爬取电影《749局》豆瓣热评”的评论:

还没有评论