二.动态网页抓取

前面爬取的网页均为静态网页,这样的网页在浏览器中展示的内容都位于HTML源代码中。但是由于主流网站使用JavaScript展现网页内容,和静态网页不同的是,使用JavaScript时,很多内容并不会出现在HTML源代码中,所以爬取静态网页的技术可能无法正常使用。因此,我们需要用到动态网页抓取的两种技术:通过浏览器审查元素解析真实网页地址和使用Selenium模拟浏览器的方法。

1 动态抓取的实例

因此,我们如果使用 AJAX 加载的动态网页,怎么爬取里面动态加载的内容呢?有两种方法:

  1. 通过浏览器审查元素解析地址
  2. 通过selenium模拟浏览器抓取

2 动态抓取的实例

方法1操作步骤:

  1. 打开浏览器“检查”功能。
  2. 找到真实的数据地址。点击对话框中的Network,然后刷新网页。此时,Network 会显示浏览器从网页服务器中得到的所有文件,一般这个过程称之为“抓包”。
  3. 爬取真实评论数据地址。既然找到了真实的地址,我们就可以直接用requests请求这个地址,获取数据。
  4. 从 json数据中提取评论。上述的结果比较杂乱,但是它其实是 json 数据,我们可以使用 json 库解析数据,从中提取我们想要的数据
import requests
import json
def single_page_comment(link):
   headers = {'User-Agent' : 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
   r = requests.get(link, headers= headers)
   # 获取 json 的 string
   json_string = r.text
   json_string = json_string[json_string.find('{'):-2]
   json_data = json.loads(json_string)
   comment_list = json_data['results']['parents']
for eachone in comment_list:
   message = eachone['content']
   print (message)
for page in range(1,4):
   link1 = "https://api-zero.livere.com/v1/comments/list?callback=jQuery112403473268296510956_1531502963311&limit=10&offset="
   link2 = "&repSeq=4272904&requestPath=%2Fv1%2Fcomments%2Flist&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&_=1531502963316"
   page_str = str(page)
   link = link1 + page_str + link2
   print (link)
   single_page_comment(link)

3 通过selenium 模拟浏览器抓取

我们可以用Python的selenium库模拟浏览器完成抓取。Selenium是一个>用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,浏>览器自动按照脚本代码做出点击,输入,打开,验证等操作,就像真正的用户在操作一样。

步骤:

  1. 找到评论的HTML代码标签。使用Chrome打开该文章页面,右键点击页面,打开“检查”选项。按照第二章的方法,定位到评论数据。
  2. 尝试获取一条评论数据。在原来打开页面的代码数据上,我们可以使用以下代码,获取第一条评论数据。在下面代码中,driver.find_element_by_css_selector是用CSS选择器查找元素,找到class为’reply-content’的div元素;find_element_by_tag_name则是通过元素的tag去寻找,意思是找到comment中的p元素。最后,再输出p元素中的text文本。
  3. 我们可以在 jupyter 中键入driver.page_source
    找到为什么没有定位到评论元素,通过排查我们发现,原来代码中的 JavaScript 解析成了一个 iframe,<iframe title=”livere” scrolling=”no”…>也就是说,所有的评论都装在这个框架之中,里面的评论并没有解析出来,所以我们才找不到div.reply-content元素。这时,我们需要加上对 iframe 的解析。
from selenium import webdriver
import time
driver = webdriver.Firefox(executable_path = r'C:\Users\santostang\Desktop\geckodriver.exe')
driver.implicitly_wait(20) # 隐性等待,最长等20秒
#把上述地址改成你电脑中geckodriver.exe程序的地址
driver.get("http://www.santostang.com/2018/07/04/hello-world/")
time.sleep(5)
for i in range(0,3):
    # 下滑到页面底部
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    # 转换iframe,再找到查看更多,点击
 driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='livere']"))
    load_more = driver.find_element_by_css_selector('button.more-btn')
    load_more.click()
    # 把iframe又转回去
    driver.switch_to.default_content()
    time.sleep(2)
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='livere']"))
comments = driver.find_elements_by_css_selector('div.reply-content')
for eachcomment in comments:
    content = eachcomment.find_element_by_tag_name('p')
    print (content.text)

selenium选择元素的方法有很多:

  • find_element_by_id:通过元素的id选择,例如:driver.find_element_by_id(‘loginForm’)
  • find_element_by_name:通过元素的name选择,driver.find_element_by_name('password')
  • find_element_by_xpath:通过xpath选择,driver.find_element_by_xpath(“//form[1]”)
  • find_element_by_link_text:通过链接地址选择
  • find_element_by_partial_link_text:通过链接的部分地址选择
  • find_element_by_tag_name:通过元素的名称选择
  • find_element_by_class_name:通过元素的id选择
  • find_element_by_css_selector:通过css选择器选择

有时候,我们需要查找多个元素。在上述例子中,我们就查找了所有的评论。因此,也有对应的元素选择方法,就是在上述的element后加上s,变成elements。
其中xpath和css_selector是比较好的方法,一方面比较清晰,另一方面相对其他方法定位元素比较准确。
除此之外,我们还可以使用selenium操作元素方法实现自动操作网页。常见的操作元素方法如下:
– clear 清除元素的内容
– send_keys 模拟按键输入
– click 点击元素
– submit 提交表单

user = driver.find_element_by_name("username")  #找到用户名输入框
user.clear  #清除用户名输入框内容
user.send_keys("1234567")  #在框中输入用户名
pwd = driver.find_element_by_name("password")  #找到密码输入框
pwd.clear  #清除密码输入框内容
pwd.send_keys("******")    #在框中输入密码
driver.find_element_by_id("loginBtn").click()  #点击登录

由于篇幅有限,有兴趣的读者,可以到selenium的官方文档查看:http://selenium-python.readthedocs.io/index.html

4 Selenium爬虫实践

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容