动态页面抓取

动态页面抓取

前面爬取的页面都是静态页面,页面展示的内容都存储在HTML源代码中。

但是,现在主流的网站都使用JavaScript 展现网页内容,和静态网页不一样的是,使用JavaScript时,很多内容都不会出现在HTML源码中。

因此,我们需要用到爬取动态网页的两种技术:

  1. 通过浏览器审查元素解析真实网页地址
  2. 使用selenium模拟浏览器获取动态网页数据

动态抓取的实例

在爬取动态网页之前,我们需要先了解一种异步更新技术——AJAX(异步JavaScriptXML

它的价值在于通过在后台与服务器进行少量数据交换就可以使网页实现异步更新

这意味着可以在不更新加载整个网页的情况下对网页的某部分进行更新。

例如,我们在看微博评论时,网页不会将所有评论全部展现,而是我们往下滑一段就出现一段评论,这就用到了异步更新技术

比如:我们在异步加载网站中,我们看到的评论数据就是使用JavaScript加载的,不会出现在网页源代码中。
在这里插入图片描述
爬取动态网页的两种方法:

  1. 通过浏览器审查元素解析真实网页地址
  2. 使用selenium模拟浏览器获取动态网页数据

解析真实地址抓取

Chrome右键点击“检查”命令,单击页面中的“Network”选项,然后刷新网页。此时Network会显示浏览器从网页服务器中得到的所有文件,这个过程被称为“抓包

因为显示的文件太多,可以按crtl+F搜索想要的内容,会自动定位到该网页,例如我们根据网页的评论搜索定位
在这里插入图片描述
在headers中我们可以看到真实地址
在这里插入图片描述

import requests
import lxml.html
import json
url='https://api-zero.livere.com/v1/comments/list?callback=jQuery112404090822790751196_1609138618610&limit=10&repSeq=4272904&requestPath=%2Fv1%2Fcomments%2Flist&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&code=&_=1609138618612'
headers={'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36'}
r=requests.get(url,headers=headers)
print(r.text)
open('html.txt','w',encoding='utf-8').write(r.text)

运行代码我们发现我们想要的评论数据就包含在响应文件中
在这里插入图片描述
接下来就是从json数据中提取评论。上述结果比较杂乱,其实这些是json数据,我们可以使用json克时解析数据,从中提取想要的信息。

这时,我们发现这个网页数据不是正确的json格式
在这里插入图片描述
因为我们这里不涉及数据清洗内容,所以我们把错误的数据手动删除掉(第一行{前面的数据和结尾的);),删除完之后即为正确的json格式,即一个字典

import json
html=open('html.txt','r',encoding='utf-8').read()
json_data=json.loads(html)
comment_list=json_data['results']['parents']# json文件中的列表
for each in comment_list:
    print(each["content"])# 列表的content字段

在这里插入图片描述
这样,我们就把评论信息提取出来了

上面我们把第一页的评论爬取出来了,如果人工找每一页的真实地址会非常的麻烦,因此我们可以根据规律使用for循环爬取

我们可以发现第一页的真实地址是:https://api-zero.livere.com/v1/comments/list?callback=jQuery1124024945189329458972_1609143449063&limit=10&offset=1&repSeq=4272904&requestPath=%2Fv1%2Fcomments%2Flist&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&code=&_=1609143449073

第二页的真实地址是:https://api-zero.livere.com/v1/comments/list?callback=jQuery11240527837944980206_1609142567812&limit=10&offset=3&repSeq=4272904&requestPath=%2Fv1%2Fcomments%2Flist&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&code=&_=1609142567814

可以发现URL地址中有两个比较重要的变量,limit代表每一页评论数量的最大值,offset表示评论页

import requests
import lxml.html
import json
url='https://api-zero.livere.com/v1/comments/list?callback=jQuery112404090822790751196_1609138618610&limit=10&repSeq=4272904&requestPath=%2Fv1%2Fcomments%2Flist&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&code=&_=1609138618612'
headers={'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36'}
def single_page_comment(url,i):
    r=requests.get(url,headers=headers)
    print(r.text)
    open('html'+str(i)+'.txt','w',encoding='utf-8').write(r.text)
for i in range(5):
    link1='https://api-zero.livere.com/v1/comments/list?callback=jQuery11240527837944980206_1609142567812&limit=10&offset='
    link2='&repSeq=4272904&requestPath=%2Fv1%2Fcomments%2Flist&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&code=&_=1609142567814'
    url=link1+str(i+1)+link2
    single_page_comment(url,i+1)

# https://api-zero.livere.com/v1/comments/list?callback=jQuery1124024945189329458972_1609143449063&limit=10&offset=1&repSeq=4272904&requestPath=%2Fv1%2Fcomments%2Flist&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&code=&_=1609143449073
# https://api-zero.livere.com/v1/comments/list?callback=jQuery11240527837944980206_1609142567812&limit=10&offset=3&repSeq=4272904&requestPath=%2Fv1%2Fcomments%2Flist&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&code=&_=1609142567814

运行代码我们可以得到每一个评论页的源代码
在这里插入图片描述

通过Selenium模拟浏览器抓取

在之前的例子中,使用Chrome 的“检查”功能找到源地址十分容易,但是有一些网站非常复杂,如天猫产品评论,使用“检查”功能很难找到调用的网页地址。除此之外,有一些数据真实地址的URL也十分冗长和复杂,有些网站为了规避这些抓取会对地址进行加密,造成其中的一些变量让人摸不着头脑。

因此,这里介绍另一种方法,即使用浏览器渲染引擎。直接用浏览器在显示网页时解析HTML、应用CSS样式并执行JavaScript的语句。这个方法在爬虫过程中会打开一个浏览器加载该网页,自动操作浏览器浏览各个网页,顺便把数据抓下来。用- -句简单而通俗的话说,就是使用浏览器渲染方法将爬取动态网页变成爬取静态网页。

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

Selenium的安装与基本介绍

pip install selenium

下载ChromeDriver,根据自己的系统下载合适的版本,下载地址
在这里插入图片描述

from selenium import webdriver
driver=webdriver.Chrome()
driver.get('baidu.com')

使用代码模拟浏览器打开baidu.com,我们会发现会报错,这时因为在同文件文件路径中不存在ChromeDriver.exe文件

webdriver.Chrome()函数的参数为ChromeDriver.exe文件的路径,我们也可以把该文件复制到同路径下
在这里插入图片描述

Selenium的实践案例

正常情况下,右键点击“检查”,其中的Elements选择就是浏览器渲染的成的静态网页代码
在这里插入图片描述

Selenium获取微博评论

from selenium import webdriver
import time
driver=webdriver.Chrome()
driver.get('https://m.weibo.cn/detail/4467107636950632')
time.sleep(5)
html=driver.page_source
open('html.txt','w',encoding='utf-8').write(html)
print(html)
comment=driver.find_elements_by_xpath('//*[@id="app"]/div[1]/div/div[4]/div[2]/div/div/div/div/div/div[2]/div[1]/div/div/h3')
for each in comment:
    content=each.text
    print(content)

在这里插入图片描述

Selenium的高级操作

Selenium中常见的操作元素方法

  • Clear清除元素的内容
  • send_keys模拟按键输入
  • Click 点击元素
  • Submit 提交表单
    在这里插入图片描述
    Selenium的高级操作
  1. 控制CSS的加载
        from selenium import webdriver
 
        f = webdriver.FirefoxProfile()
        f.set_preference("permissions.default.stylesheet",2)
 
        driver = webdriver.Firefox(firefox_profile = f)
        driver.get('https://www.douban.com/')
  1. 控制图片文件的显示
          from selenium import webdriver
 
          f = webdriver.FirefoxProfile()
          f.set_preference("permissions.default.image",2)
 
          driver = webdriver.Firefox(firefox_profile = f)
          driver.get('https://www.douban.com/')
  1. 控制JavaScript的运行
           from selenium import webdriver
 
           f = webdriver.FirefoxProfile()
           f.set_preference("javascript.enabled",False)
 
           driver = webdriver.Firefox(firefox_profile = f)
           driver.get('https://www.douban.com/')

Selenum爬虫实践:深圳短租数据

项目实践
from selenium import webdriver
import time
url='https://www.airbnb.cn/s/%E6%B7%B1%E5%9C%B3%E5%B8%82/homes?refinement_paths%5B%5D=%2Fhomes&screen_size=large&checkin=2020-12-28&checkout=2020-12-29&host_promotion_type_ids%5B%5D=1&host_promotion_type_ids%5B%5D=8'
driver=webdriver.Chrome()
driver.get(url)
def driver_run(driver):
    time.sleep(5)
    comment=driver.find_elements_by_xpath('/html/body/div[3]/main/div/div/div/div[3]/div/div/section/div/div/div[2]/div/div/div[2]/div/div/div/div/div')
    for each in comment:
        name=each.find_element_by_xpath('div/div/div/div/div/div/div/div[2]/div/div/a/div[1]/div[2]/div/div').text
        print(name)
driver_run(driver)
for i in range(0,14):
    driver.find_element_by_xpath('//*[@id="site-content"]/div/div/div/div[3]/div/div/div/div[1]/div[1]/a[6]/svg/g/path').click()
    driver_run(driver)
自我实践题

爬取农贸市场所有商品名称与价格

from selenium import webdriver
import time
url='http://www.gznw.com/eportal/ui?pageId=595091'
driver=webdriver.Chrome()
driver.get(url)
def driver_run(driver):
    time.sleep(5)
    comment=driver.find_elements_by_xpath('//*[@id="5c96d136291949729295e25ea7e708b7"]/div[2]/div[2]/table/tbody/tr')
    for each in comment:
        name=each.find_element_by_xpath('td[2]').text
        price=each.find_element_by_xpath('td[4]').text
        print(name,"  ",price)
driver_run(driver)
for i in range(0,2014):
    driver.find_element_by_xpath('//*[@id="5c96d136291949729295e25ea7e708b7"]/div[2]/div[3]/table/tbody/tr/td/a[3]').click()
    driver_run(driver)

在这里插入图片描述

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值