在练习爬虫过程中,拿阿里的tb练了练手,抓取其中商品的名称,标价,地址,店铺,商品图片等

并将信息写入excel表格,将图片存入相应的文件夹中。

分析某宝页面,发现页面源码当中并没有我们想要的信息,通过抓包工具分析

python爬虫 快递 信息 python爬取物流信息_selenium

数据在如上图的接口中,并且这个接口的cookie是动态的,所以通过传统的requests需要较为复杂的js逆向知识。所以这里可以利用selenium自动化框架通过定位Xpath来抓取,较为简单方便,抓取速度与requests差不多,并且只要掌握Xpath语法即可。

import requests
from selenium import webdriver
import time
import random
import xlwt
from selenium.webdriver.common.by import By

首先上方为需要用到的包,主要为selenium自动操作chrome浏览器,requests用于请求下载图片,xlwt用于将数据写入excel。

首先用xpath定位目标元素,在登录界面不详细做过多的赘述。这里直接到需要抓取的页面中。

python爬虫 快递 信息 python爬取物流信息_python爬虫 快递 信息_02

通过分析xpath,我们可以知道每一个商品信息都放在class属性为items下的所有div标签,所以我们可以先获取这里的所有div标签,然后遍历div标签,得到具体的信息。

divs = driver.find_elements(by=By.XPATH, value='//div[@class="grid g-clearfix"]/div/div')  # 所有的div标签

继续分析每个div下的标签,可以看到:

python爬虫 快递 信息 python爬取物流信息_python_03

 

 付款人数在deal-cnt中,地址在location中,详情页地址在row row-2 title中的a标签下。

python爬虫 快递 信息 python爬取物流信息_python爬虫 快递 信息_04

图片的地址在class=“pic”下的a标签中的data-src的值。分析完成,下面就是进入代码环节:

def get_data():
    # headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53",
    #          "Host": "g-search1.alicdn.com"}
    global col
    global row
    divs = driver.find_elements(by=By.XPATH, value='//div[@class="grid g-clearfix"]/div/div')  # 所有的div标签

    for div in divs:
        test = div.find_element(by=By.XPATH, value='.//div[@class="row row-2 title"]/a').text  # 商品名字
        price = div.find_element(by=By.XPATH, value='.//strong').text + '元'  # 商品价格
        deal = div.find_element(by=By.XPATH, value='.//div[@class="deal-cnt"]').text  # 付款人数
        name = div.find_element(by=By.XPATH, value='.//div[@class="shop"]/a/span[2]').text  # 店铺名称
        location = div.find_element(by=By.XPATH, value='.//div[@class="location"]').text  # 店铺地点
        detail_url = div.find_element(by=By.XPATH, value='.//div[@class="row row-2 title"]/a').get_attribute(
            'href')  # 详情页地址
        img_data_url = div.find_element(by=By.XPATH,
                                        value='.//div[@class="pic-box J_MouseEneterLeave J_PicBox"]//a/img').get_attribute(
            'data-src')
        if 'http' not in img_data_url:  # 少量url有前缀http,这里处理一下
            img_data_url = "http:" + img_data_url

这里就是获取信息的函数。信息获取完毕,将信息写入excel表格中,将图片批量下载至相应文件夹中即可。完整代码如下:

import requests
from selenium import webdriver
import time
import random
import xlwt
from selenium.webdriver.common.by import By


def get_data():
    # headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53",
    #          "Host": "g-search1.alicdn.com"}
    global col
    global row
    divs = driver.find_elements(by=By.XPATH, value='//div[@class="grid g-clearfix"]/div/div')  # 所有的div标签

    for div in divs:
        test = div.find_element(by=By.XPATH, value='.//div[@class="row row-2 title"]/a').text  # 商品名字
        price = div.find_element(by=By.XPATH, value='.//strong').text + '元'  # 商品价格
        deal = div.find_element(by=By.XPATH, value='.//div[@class="deal-cnt"]').text  # 付款人数
        name = div.find_element(by=By.XPATH, value='.//div[@class="shop"]/a/span[2]').text  # 店铺名称
        location = div.find_element(by=By.XPATH, value='.//div[@class="location"]').text  # 店铺地点
        detail_url = div.find_element(by=By.XPATH, value='.//div[@class="row row-2 title"]/a').get_attribute(
            'href')  # 详情页地址
        img_data_url = div.find_element(by=By.XPATH,
                                        value='.//div[@class="pic-box J_MouseEneterLeave J_PicBox"]//a/img').get_attribute(
            'data-src')
        if 'http' not in img_data_url:  # 少量url有前缀http,这里处理一下
            img_data_url = "http:" + img_data_url
        with open("./商品图片/{}.jpg".format(row), 'wb') as fp:
            fp.write(requests.get(img_data_url).content)  # 下载商品图片到文件夹
        work_sheet.write(row, col, test)  # 写入excel
        work_sheet.write(row, col + 1, price)
        work_sheet.write(row, col + 2, deal)
        work_sheet.write(row, col + 3, name)
        work_sheet.write(row, col + 4, location)
        work_sheet.write(row, col + 5, detail_url)
        row += 1
        print(test, price, deal, name, location, detail_url)


if __name__ == '__main__':
    div_list = ["商品名字", "商品价格", "付款人数", "店铺名称", "店铺地点", "详情页地址"]
    col = 0  # 设置行、列
    row = 1
    work_book = xlwt.Workbook(encoding='utf-8')  # 创建工作簿
    work_sheet = work_book.add_sheet('tb_shopping')  # 创建一张表
    # pattern = xlwt.Pattern()  # 设置单元格颜色
    # pattern.pattern = xlwt.Pattern.SOLID_PATTERN
    # pattern.pattern_fore_colour = 5
    for i in range(6):  # 设置标头
        work_sheet.col(i).width = 4444
        work_sheet.write(0, i, div_list[i])
    word = input('请输入要搜索的关键字:')
    driver = webdriver.Chrome("D:/chrome/chromedriver.exe")
    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",  # 修改浏览器属性,跳过滑动验证
                           {"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})
    driver.get('https://www.taobao.com/')
    driver.implicitly_wait(10)  
    driver.maximize_window()

    driver.find_element(by=By.XPATH, value='//*[@id="q"]').send_keys(word)
    time.sleep(random.randint(1, 3))
    driver.find_element(by=By.XPATH, value='//*[@id="J_TSearchForm"]/div[1]/button').click()
    time.sleep(random.randint(1, 3))

    """用户账号及密码登录"""
    driver.find_element(by=By.XPATH, value='//*[@id="fm-login-id"]').send_keys('......')  # 输入账号密码
    time.sleep(random.randint(1, 3))
    driver.find_element(by=By.XPATH, value='//*[@id="fm-login-password"]').send_keys('.......')
    time.sleep(random.randint(1, 3))
    driver.find_element(by=By.XPATH, value='//*[@id="login-form"]/div[4]/button').click()
    time.sleep(random.randint(1, 3))
    for page in range(0, 7):
        print(f'正在爬取第{page + 1}页')
        get_data()
        driver.find_element(by=By.XPATH, value='//li[@class="item next"]/a[@class="J_Ajax num icon-tag"]').click()
        time.sleep(random.randint(2, 3))
    work_book.save("自行命名.xls")

总结:通过selenium爬取时,可以绕过一些复杂的js逆向而抓取到我们想要的信息,但如果是大量的信息的话,速度上面也许会慢一些。总之,各有利弊。