当前位置 博文首页 > 孤寒者的博客:使用selenium爬取天猫商品

    孤寒者的博客:使用selenium爬取天猫商品

    作者:[db:作者] 时间:2021-07-25 18:33

    1.直接上代码:(解析和思路都在代码里!)

    from selenium import webdriver
    from selenium.common.exceptions import TimeoutException
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.common.keys import Keys
    
    from pyquery import PyQuery as pq
    
    import time
    
    browser = webdriver.Chrome()
    # 等待的使用——使用WebDriverWait对象,指定最长等待时间为10S。
    wait = WebDriverWait(browser, 10)
    KEYWORD = 'iPad'
    
    def login_tianmao():
        """
        扫码登录天猫,运行之后会自动打开登录二维码界面并等待,你只需拿起手机扫码登录即可!
        :return:
        """
        url = 'https://login.tmall.com/'
        browser.get(url)
        browser.maximize_window()
        # 因为二维码界面在嵌套的iframe框架中,所以先跳转进入该iframe
        browser.switch_to.frame('J_loginIframe')
        # 点击出现登录二维码
        browser.find_element_by_class_name('icon-qrcode').click()
        time.sleep(6)
    
        # 显示等待——如果在上面设置的最长等待时间10S内成功匹配了等待条件,也就是说页面元素成功加载出来了,就立即返回相应结果并继续向下执行
        # 否则到了最大等待时间还没有加载出来时,就直接抛出超时异常!
        # 此处等待条件为判断天猫是否登录成功——如果登录成功会出现搜索框!
        input = wait.until(
            EC.presence_of_element_located((By.CLASS_NAME, 's-combobox-input'))
        )
        # 输入搜索关键字
        input.send_keys(KEYWORD)
        time.sleep(1)
        # 使用Keys的ENTER,相当于.click()函数
        input.send_keys(Keys.ENTER)
    
    
    def index_page(page):
        """
        抓取索引页
        :param page:页码
        :return:
        """
        print("正在爬取第", page , "页")
        try:
            if page == 1:
                login_tianmao()
            else:
                # selenium执行JS代码,下滑操作——使页面下滑至出现页码输入框,便于观察!
                js = 'scrollTo(0,4200)'     # js语句
                browser.execute_script(js)  # 执行js的方法
                # 显示等待——等待条件:定位到跳转页码输入框!
                input = wait.until(
                    EC.presence_of_element_located((By.CLASS_NAME, 'ui-page-skipTo'))
                )
                # 显示等待——等待条件:定位到可点击的页码跳转确定按钮!
                submit = wait.until(
                    EC.element_to_be_clickable((By.CLASS_NAME, 'ui-btn-s'))
                )
                # 清空输入框,输入下一页的页码,点击!
                input.clear()
                input.send_keys(page)
                submit.click()
            # 如果判断有没有跳转到对应的页码——观察可知只需判断当前高亮的页码数是当前的页码数即可!!!
            # 显示等待——等待条件:检测当前高亮的页码节点是不是我们传过来的页码数,如果是就证明页面成功跳转到了这一页!
            # .text_to_be_present_in_element()——它会等待指定的文本出现在某一个节点里面时即返回成功!
            wait.until(
                EC.text_to_be_present_in_element((By.CSS_SELECTOR, '.ui-page .ui-page-wrap .ui-page-num .ui-page-cur'),
                str(page))
            )
            # 显示等待——等待条件:定位到每个商品的信息块!
            wait.until(
                EC.presence_of_element_located((By.CSS_SELECTOR, '#J_ItemList')))
            # 提取商品信息!
            get_products()
        except TimeoutException:
            index_page(page)
    
    def get_products():
        """
        提取商品数据   使用pyquery进行解析!
        :return:
        """
        html = browser.page_source
        # 构造PyQuery解析对象
        doc = pq(html)
        # 提取商品列表,此处匹配到的是整个页面的每个商品,它的匹配结果是多个,所以需要使用.items()方法对它进行遍历
        # 调用items()方法后,会得到一个生成器,遍历即可获取每个值。遍历之后的每个值依旧是PyQuery类型。
        items = doc('#J_ItemList .product-iWrap').items()
        for item in items:
            product = {
                #商品图片链接
                'image': item.find('.productImg-wrap .productImg img').attr('src'),
                # 商品价格
                'price': item.find('.productPrice').text(),
                # 商品成交量
                'deal': item.find('.productStatus').text(),
                # 商品名称
                'title': item.find('.productTitle a').attr('title'),
                # 商品店铺
                'shop': item.find('.productShop').text(),
            }
            print(product)
            # 写入本地txt
            with open('1.txt', 'a+', encoding='utf-8') as f:
                f.write(str(product))
                f.write('\n')
    
    # 模拟抓取十页!
    MAX_PAGE = 10
    def main():
        for i in range(1, MAX_PAGE + 1):
            index_page(i)
        browser.quit()
    
    if __name__ == '__main__':
        main()
    

    2.模拟代码运行截图:

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    cs
    下一篇:没有了