来看我能坚挺多久------番外篇1

99 阅读4分钟

昨天临时接了一单,下班后开搞,导致没学习整理。所以第三天就简单总结下接单的代码。

=======================正文=======================

订单内容:

获取某个电商网站的所有商品信息,包括链接、价格、佣金、标题等信息。

 思路:

1、分析网站,发现网站是下滑加载商品,每次10个。 image.png

2、分析接口,每次加载商品就会调用一次接口,但是传参加密了。 image.png

3、由于是简单的任务,不考虑框架和分布式等。

4、技术选型就在requests库还是selenium库。因为requests库还要考虑传参问题,selenium已经很久没用了,就决定使用selenium。

5、selenium主要针对网页源码进行操作,开始分析网页源码。发现每次刷新都会动态加载div标签。 image.png

6、每次加载商品后,不是处于网页最底部,根据此判断商品是否加载完全部。没加载完就下滑加载即可。

7、xpath定位元素,获取所需的数据,使用pandas存到excel。

思路分析完毕,开干!

1、搭建环境,用的是chrome浏览器,版本 115.0.5790.170(正式版本)。该版本好像不需要下载webdriver,我是没找到对应webdriver版本,然后启用成功啦!!!

2、导入各种包,ps:第三方库下载都很简单,就不在这写啦!

# 有一步需要用到requests.get
import requests
# 导入selenium的webdriver
from selenium import webdriver
# 本次不用显式等待,这块导入可忽略
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 用xpath查找元素位置
from selenium.webdriver.common.by import By
# 用pandas导入数据
import pandas as pd
# 用于强制等待
import time

3、封装函数

def get_resp(url,headers):
    resp = requests.get(url=url,headers=headers)
 
    return resp
 
def do_excel(data):
    data = data
    df = pd.DataFrame(data,columns=['id','链接','产品名称'])
    df.to_excel('xxx.xlsx',index=False)
 
class browser_driver:
    def __init__(self):
        self.driver = webdriver.Chrome()
        # 窗口最大化
        self.driver.maximize_window()
        # 加载网页
        self.driver.get(url)
 
    def get_page_source(self):
        time.sleep(2)
        html = self.driver.page_source
        return html
 
    def brower_quit(self):
        self.driver.quit()
 
    def drop_down(self):
        time.sleep(2)
        # 获取当前页面得高度
        last_height = self.driver.execute_script('return document.body.scrollHeight')
        print('当前浏览器高度{}'.format(last_height))
 
        sum = 1
        len = 1
        while True:
            # 下拉操作
            self.driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
            time.sleep(2)
 
            """ 
            佣金
            日
            月
            总销量
            价格 
            标题 
            点进去标题里后的佣金销售链接 
            """
 
            # 获取页面内容
            html = self.get_page_source()
            total = get_resp(url=api_url,headers=headers).json()['data']['page_info']['total_count']
            page =  get_resp(url=api_url,headers=headers).json()['data']['page_info']['total_page']
 
            if len <= (page-1)*10:
                for i in range(len,len+10):
                    #每次for循环后字典实例化
                    list_1 = []
 
                    # 标题
                    title = self.driver.find_element(By.XPATH,f"//div[@class='goods-list flex flex-flow-row-wrap']//*[@class='item'][{i}]//div[@class='mb5']//div[@class='goods-block']//div[@class='inner-box']//div[2]//div//div[1]//span[@class='ml4']")
                    # 链接
                    href = self.driver.find_element(By.XPATH,f"//div[@class='goods-list flex flex-flow-row-wrap']//*[@class='item'][{i}]//div//a").get_attribute('href')
 
                    # 把爬取的数据保存到字典
                    list_1.append(i)
                    list_1.append(href)
                    list_1.append(title.text)
 
                    # 添加到列表
                    list.append(list_1)
                    print("len:",len)
 
            else:
                val = total - (len)
                print(val)
                print(len+val)
                for i in range(len, len + val-1):
                    # 每次for循环后字典实例化
                    list_1 = []
 
                    # 标题
                    title = self.driver.find_element(By.XPATH, f"//div[@class='goods-list flex flex-flow-row-wrap']//*[@class='item'][{i}]//div[@class='mb5']//div[@class='goods-block']//div[@class='inner-box']//div[2]//div//div[1]//span[@class='ml4']")
                    # 链接
                    href = self.driver.find_element(By.XPATH, f"//div[@class='goods-list flex flex-flow-row-wrap']//*[@class='item'][{i}]//div//a").get_attribute('href')
 
                    # 把爬取的数据保存到字典
                    list_1.append(i)
                    list_1.append(href)
                    list_1.append(title.text)
 
                    # 添加到列表
                    list.append(list_1)
                    print("len:",len)
 
 
            print(list)
            print('*' * 20)
            len = len + 10
 
            # 获取当前页面的高度
            new_height = self.driver.execute_script('return document.body.scrollHeight')
 
            # 判断是否到达页面底部
            if last_height == new_height:
                break
 
            last_height = new_height
 
        do_excel(list)
 
    def test(self):
        self.drop_down()
        self.brower_quit()

4、执行&产出

if __name__ == '__main__':
    browser_driver().test()

image.png

总结!

整体使用到的技术有selenium+requests+pandas+javascript,原本计划2个小时完成的脚本,结果花费了4个小时。一方面是selenium很久没用,需要查阅写资料。另一方面,在编写过程中也遇到些问题,花费了些时间。

问题1:要获取属性相同,但下标不一样的元素位置?所有加起来大概有487个。

方法:设置动态的xpath元素定位,需要找准下标位置,以确保找到的元素是唯一值。

问题2:一次性加载完所有商品后,页面源码太多,导致打印出来的源码不存,收集信息不全。

方法:每次加载商品后,先获取商品信息,保存到列表里。最后全部商品加载完后,再存到另一个列表,信息则会收集完整。

问题3:每次下滑会加载10个商品,到最后一轮加载,商品信息只有7个。因for循环遍历每次都是10个10个的进行,会导致找不到下标为488、489、490的元素而报错。

方法:使用if...else...,单独处理最后一轮加载的商品信息。弊端是每次更新代码要更新两处地方,懒得去优化,将就用了。。。