利用selenium爬取动态渲染的页面

说明

    对于有些网站来说,他的网页不是纯HTML标签加载出来的,而是用javascript渲染出来的,对于这样的网页,如果单纯的靠正则表达式、XPath来解析是行不通的。对于这样的网页,一是我们可以分析ajax请求,分析ajax参数发现其规律,自行模拟ajax请求(对于如何利用ajax参数爬取网页数据博主前面已经提到过),二是如果通过ajax参数无法发现其规律,我们可以利用selenium来模拟浏览器,说白了我们通过利用selenium和chrome driver就可以通过利用代码来模拟用户在浏览器上的各种交互了。 

分析

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
import re
from urllib.parse import quote
import csv
from pyquery import PyQuery
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser=webdriver.Chrome()  #所用浏览器为谷歌浏览器
wait=WebDriverWait(browser,3)  #设置响应的最长等待时间为3秒
KEYWORD='python'   #提取出要爬取的关键字
#定义函数,传入爬取页码进行爬取
def get_one_page(page):
    print('正在爬取第'+str(page)+'页')
    #quote函数对中文进行url编码,防止乱码
    url='https://s.taobao.com/search?q='+quote(KEYWORD)
    try:
        browser.get(url)   #get方式请求网页
        if page>1:         #如果页码大于1,先进行跳页操作
            input=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'.form .input.J_Input'))) #获取到跳页输入框
            submit=wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.form .btn.J_Submit')))#获取到确定按钮
            input.clear()  #模拟清空页码
            input.send_keys(page) #模拟输入页码
            submit.click()  #模拟点击操作
        wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR,'ul.items>li.item.active>span.num'),str(page))) #确认已经跳转到目标页码
        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'.m-itemlist .items .item')))   #等待商品列表加载完成
        #解析得到商品列表
        html=browser.page_source  #获取该页的源代码
        doc=PyQuery(html)         #生成PyQuery对象
        items=doc('.m-itemlist .items .item').items()   #得到商品列表的生成器
        for item in items:
            price=item.find('.price').text()   #得到每件商品的价格
            price=re.sub('¥\n','',price)       #对得到的价格进行处理
            product={
                'store':item.find('.shop').text(),
                'image':item.find('.pic .img').attr('data-src'),
                'price':price
            }                                   #把商品的店铺,图片url以及价格存到字典中
            print(product)
            yield product                      #将每个商品的字典添加到生成器当中
    except TimeoutException:
        get_one_page(page)     #请求超时重新调用该方法再一次请求

if __name__=='__main__':
    with open('result.csv','a',newline='') as csvfile:   #以追加的方式打开本地csv文件,newline参数用来去掉空白行
        filenames=['store','image','price']              #表头
        csvwriter=csv.DictWriter(csvfile,filenames)
        csvwriter.writeheader()                            #写入表头
        for page in range(1,101):                          #循环100个生成器(100页)
            products=get_one_page(page)                    #得到每页的所有商品
            for product in products:                      #遍历每页的商品
                csvwriter.writerow(product)                #每个商品的信息写到csv当中
    print('爬取完毕')

由于本人比较懒,在代码段直接做了详细的解释了,在此不再赘述!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值