【爬虫】python使用selenium抓取淘宝中的商品数据

前言

最近因为项目需要又得抓一批数据,和之前的scrapy不同,这次选择使用selenium来爬取。两种方法的区别如下:

  • scrapy之类的库是基于网络请求来爬取的,也就是直接向目标服务器发送http请求,在这个过程中需要自己构造请求字段也就是json格式的request body。
  • selenium一类的库是基于自动化测试的,我们只需要知道想要访问的链接就好,其它的(异步加载图片、信息之类的)交给浏览器来做。也因此在使用时需要额外下载浏览器以及对应驱动,比如googledriver。

总而言之,虽然selenium在速度上是远远不如直接发请求的scrapy一类的库的,但可以完美地规避反爬策略,因为自动化测试相当于是模拟人去访问一个网站,因此还可以进行网页自动截图之类的操作,可以说是非常简单方便。

安装

  1. 下载selenium库:pip install selenium
  2. 下载浏览器驱动:一般来说就是ChromeDriver,先看自己电脑上的Chrome版本,然后在给出的链接中下载对应版本的ChromeDriver。
  3. 将ChromeDriver加到环境变量里,方法就不多说了,网上随便找找就有,可以参考[windows环境变量配置/linux、mac环境变量配置]

对网页进行滚动截屏

首先是一个比较简单的应用,就是对整个网页进行截屏,并且在网页长度超出窗口长度时可以滚动截屏并自动拼接。主要思想是获取网页长度page_height与窗口长度window_height,然后循环定位到网页的不同位置来截图,并把截图都拼接到一起。话不多说直接上代码:

from io import BytesIO
import traceback
from time import sleep
from PIL import Image
import numpy as np
from selenium import webdriver

def url_screenshot(ad_url, index):
    try:
        chrome_options = webdriver.ChromeOptions()
        chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])
        chrome_options.add_argument('--headless')	# 后台静默运行
        driver = webdriver.Chrome(options=chrome_options)
        driver.get(ad_url)
        driver.fullscreen_window()  # 全屏窗口
        # 当前窗口的高度
        window_height = driver.get_window_size()['height']  
        # 页面高度
        page_height = driver.execute_script('return document.documentElement.scrollHeight')  
        print('window_height:{},page_height:{}'.format(window_height,page_height)
        img_binary = driver.get_screenshot_as_png()
        base_img = np.array(Image.open(BytesIO(img_binary)))

        if page_height > window_height:
            n = page_height // window_height  # 需要滚动的次数
            for i in range(n):
                driver.execute_script(f'document.documentElement.scrollTop={window_height*(i+1)};')
                sleep(5)
                img = np.array(Image.open(BytesIO(driver.get_screenshot_as_png())))
                if i==n-1:
                    out = window_height * (i + 1) - (page_height - window_height)
                    img = img[2*out:]
                base_img = np.append(base_img, img, axis=0)  # 拼接图片
        driver.quit()
        Image.fromarray(base_img).save("{}.png".format(index))	# 保存图片
    except:
        traceback.print_exc()

if __name__ == '__main__':
    with open('url_list','r') as fp:	# 把待截图的网页链接写在一个文件里,每行一个链接
        lines = fp.readlines()
        index = 0
        for line in lines:
            index+=1
            url_screenshot(line.strip(),index)
            print('get url:{}'.format(line))

获取淘宝商品数据

接下来一个稍微复杂一点的例子,通过关键词搜索来爬取淘宝商品的图片。
流程是:

  • run、getPage:通过关键词构造商品查询链接,并访问。
  • getItem:针对查询结果,获取每个商品详情页的链接并访问,同时翻页。
  • getItemDetail:获取商品详细信息,这里只获取了商品中包含的图片信息,想要其他信息可以在此构造别的xpath解析路径来获取。

整个过程没什么难点,主要就是分析获取的html界面,然后解析里面的元素结构,编写xpath来获取里面的某个元素。可以参考之前的关于scrapy的博客:https://blog.csdn.net/qq_34392457/article/details/117029090,这里对于如何分析一个网页的html写得更详细。

import cv2
import numpy as np
from lxml import etree
from selenium import webdriver
import time
import requests
import os
import shutil

class Crawler_taobao_images:
    def __init__(self):
        self.query_url = 'https://s.taobao.com/search?q={}&imgfile=&js=1&stats_click=search_radio_all%3A1&initiative_id=staobaoz_20210913&ie=utf8'
        chrome_options = webdriver.ChromeOptions()
        chrome_options.add_argument("--disable-infobars")
        chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])
        chrome_options.add_argument('--headless')
        self.driver = webdriver.Chrome(options=chrome_options)
        self.sleep_time = 3
        self.save_img_path = 'result/'
        if os.path.exists(self.save_img_path):
            shutil.rmtree(self.save_img_path)
        os.makedirs(self.save_img_path)
        self.image_index = 0

    def run(self):
        querys = ['酒']
        for query in querys:
            site_url = self.query_url.format(query)
            self.getPage(site_url)

    def getPage(self, site_url):
        self.driver.get(site_url)
        time.sleep(self.sleep_time)
        print(self.driver.title)
        self.getItem(site_url)

    def getItem(self,site_url):
        html = self.driver.page_source.encode('utf-8')
        print('start parse the html')
        selector = etree.HTML(html)
        #itemList = selector.xpath("//div[@class='item J_MouseOnverReq ')/div[1]/")
        itemList = selector.xpath("//*[@id='mainsrp-itemlist']/div/div/div[1]/*")
        # 循环遍历该页所有商品
        for item in itemList:
            link = item.xpath("./div[contains(@class, 'pic-box')]/div[contains(@class, 'pic-box-inner')]/div[@class='pic']/a/@href")[0]
            if "https://" not in link:
                link = "https://" + link
            print("into: ", link)
            # 进入宝贝详情页 开始爬取里面的图片资料
            try:
                self.getItemDetail(link)
            except:
                print("get link {} error!!!".format(link))

        # 获取分页信息
        next_page_value = selector.xpath("//*[@id='mainsrp-pager']/div/div/div/ul/li[contains(@class,'next')]/a/@data-value")
        print("next page: ", next_page_value)
        if len(next_page_value) == 0:
            print('没有下一页了')
        else:
            site_url_p = site_url + '&s={}'.format(next_page_value[0])
            print('加载下一页内容:', site_url_p)
            self.getPage(site_url_p)

    def getItemDetail(self, link):
        chrome_options = webdriver.ChromeOptions()
        chrome_options.add_argument("--disable-infobars")
        chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])
        chrome_options.add_argument('--headless')
        newDriver = webdriver.Chrome(options=chrome_options)
        newDriver.get(link)
        time.sleep(self.sleep_time)

        print(newDriver.title)

        html = newDriver.page_source.encode('utf-8')
        selector = etree.HTML(html)

        # 获取图片略缩链接
        image_srcs = selector.xpath("//div[@class='tb-thumb-content']/ul/li/a/img/@src")
        for image_src in image_srcs:
            # 找较高分辨率的图片
            image_src = image_src.replace('60x60','430x430')
            imglink = 'https:' + image_src
            print('imglink:{}'.format(imglink))
            image_path = os.path.join(self.save_img_path, '{}.jpg'.format(self.image_index))
            self.saveImg(imglink, image_path)
            with open(image_path, 'wb') as f:
            	f.write(requests.get(imglink).content)
            self.image_index += 1
        newDriver.quit()


if __name__ == '__main__':
    # 修改keyword便可以修改搜索关键词 建议也修改存储目录
    tb = Crawler_taobao_images()
    tb.run()
  • 0
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值