美文网首页Python爬虫
爬取淘宝商品列表

爬取淘宝商品列表

作者: 若小北00 | 来源:发表于2019-02-20 09:12 被阅读0次

    在解决了淘宝登录问题以后就开始进行淘宝商品的爬取,住要是利用Selenium抓取淘宝商品并用pyquery解析得到商品的图片、名称、价格、购买人数、店铺名称和店铺所在地信息,并将其保存到Excel中具体实现可以参考GitHub:爬取淘宝商品列表

    登录淘宝

    关于自动登录淘宝的问题上篇已经介绍过淘宝爬虫之自动登录

    跳转分类搜索页面

    在登录成功以后,我们直接跳转到需要分类的搜索页面,抓取的入口就是淘宝的搜索页面,例如搜索面膜:https://s.taobao.com/search?q=面膜,这个链接可以通过直接构造参数访问,显示的就是第一页的搜索结果,

    商品搜索.png

    在页面下方,有一个分页导航,其中既包括前5页的链接,也包括下一页的链接,同时还有一个输入任意页码跳转的入口,这里商品的搜索结果一般最大都为100页,要获取每一页的内容,只需要将页码从1到100顺序遍历即可,页码数是确定的。所以,直接在页面跳转文本框中输入要跳转的页码,然后点击“确定”按钮即可跳转到页码对应的页面。

    页码和跳转.png
    当然也可以通过通过获取'下一页'标签来获取下页的数据,我看到有些人是通过点击下一页来获取列表的数据,例如python采集淘宝教程!但是解析处理起来会有些麻烦,而且遇到错误解析中断的情况下不好做后续处理,如果感兴趣的话可以参考上面的教程

    解析商品列表

    根据构造的URL:https://s.taobao.com/search?q=面膜。来获取商品列表,参数q就是要搜索的关键字。只要改变这个参数,即可获取不同商品的列表。这里我们将商品的关键字定义成一个变量,然后构造URL。
    然后,就需要用Selenium进行抓取了:

        def index_page(self, page):
            """
            根据页码获取商品列表
            :param page: 页码
            """
            print('正在爬取第', page, '页')
            self.page = page
            try:
                if page == 1:
                    url = 'https://s.taobao.com/search?q=' + quote(KEYWORD)
                    self.browser.get(url)
                if page > 1:
                    input = self.wait.until(
                        EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager div.form > input')))
                    submit = self.wait.until(
                        EC.element_to_be_clickable((By.CSS_SELECTOR, '#mainsrp-pager div.form > span.btn.J_Submit')))
                    input.clear()
                    input.send_keys(page)
                    submit.click()
                self.wait.until(
                    EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#mainsrp-pager li.item.active > span'), str(page)))
                self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.m-itemlist .items .item')))
                self.get_products()
            except NoSuchElementException:
                self.browser.get_screenshot_as_file('error.png')
                self.index_page(page)
    

    KEYWORD :搜索商品的关键字
    在登录成功以后,然后指定一个关键词,如面膜,然后跳转到相应的搜索页面,然后调用index_page()方法,根据page获取相关的商品列表页。

    页码跳转.jpg

    在这之前我们先获取输入框和确定按钮,首先先清空了输入框,此时调用clear()方法即可。随后,调用send_keys()方法将页码填充到输入框中,然后点击“确定”按钮,然后等待页面加载。

    等待商品列表加载

    等待加载时,我们使用了WebDriverWait对象,它可以指定等待条件,等待页面加载完成,找到某个条件发生后再继续执行后续代码,如果超过设置时间检测不到则抛出异常

    WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
    driver:WebDriver 的驱动程序(Ie, Firefox, Chrome 或远程)
    timeout:最长超时时间,默认以秒为单位
    poll_frequency:休眠时间的间隔(步长)时间,默认为 0.5 秒
    ignored_exceptions:超时后的异常信息,默认情况下抛 NoSuchElementException 异常
    
    如1:element = WebDriverWait(driver, 10).until(lambda x : x.find_element_by_id("id")) 
    element.send_keys("selenium")
    
    如2:element = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_id(“Id”))
    
    is_disappeared = WebDriverWait(driver, 30, 1, (ElementNotVisibleException)).until_not(lambda x: x.find_element_by_id(“someId”).is_displayed())
    

    WebDriverWai()一般由 unit()或 until_not()方法配合使用:

    until(method, message=’’)     
    

    调用该方法提供的驱动程序作为一个参数,直到返回值不为 False。

    until_not(method, message=’’)    
    

    调用该方法提供的驱动程序作为一个参数,直到返回值为 False。

    self.wait = WebDriverWait(self.browser, 10, poll_frequency=1)
    

    这里指定为最长10秒。如果在这个时间内成功匹配了等待条件,也就是说页面元素成功加载出来了,就立即返回相应结果并继续向下执行,否则到了最大等待时间还没有加载出来时,就直接抛出超时异常。

    比如,我们最终要等待商品信息加载出来,就指定了presence_of_element_located这个条件,然后传入了.m-itemlist .items .item这个选择器,而这个选择器对应的页面内容就是每个商品的信息块,可以到网页里面查看一下。如果加载成功,就会执行后续的get_products()方法,提取商品信息。

    解析商品列表数据

    下面是使用get_products()方法来解析商品列表的,这里我们直接获取页面源代码,然后用pyquery进行解析,首先,调用page_source属性获取页码的源代码,然后构造了PyQuery解析对象,接着提取了商品列表,此时使用的CSS选择器是#mainsrp-itemlist .items .item,它会匹配整个页面的每个商品。它的匹配结果是多个,所以这里我们又对它进行了一次遍历,用for循环将每个结果分别进行解析,每次循环把它赋值为item变量,每个item变量都是一个PyQuery对象,然后再调用它的find()方法,传入CSS选择器,就可以获取单个商品的特定内容了。因为我现在要把数据写入到Excel中所以要构造一个二维数据,当然也可以通过构造对象存到数据库中,具体实现如下:

        def get_products(self):
            """
            提取商品数据
            """
            print('解析网页数据')
            html = self.browser.page_source
            doc = pq(html)
            items = doc('#mainsrp-itemlist .items .item').items()
            products = []
            for item in items:
                product = list()
                product.append(item.find('.pic .img').attr('data-src'))
                product.append(item.find('.price').text())
                product.append(item.find('.deal-cnt').text())
                product.append(item.find('.title').text())
                product.append(item.find('.shop').text())
                product.append(item.find('.location').text())
                # product = {
                #     'image': item.find('.pic .img').attr('data-src'),
                #     'price': item.find('.price').text(),
                #     'deal': item.find('.deal-cnt').text(),
                #     'title': item.find('.title').text(),
                #     'shop': item.find('.shop').text(),
                #     'location': item.find('.location').text()
                # }
                products.append(product)
            self.__write_product(products)
    

    保存数据并跳转下一页面

    数据的保持主要是通过写入Excel进行的,写入Excel的用用法之前介绍过

        def __write_product(self, products):
            titles = ['图片', '价格', '销量', '标题', '店铺', '归属地']
            if self.page == 1:
                for num in range(len(titles)):
                    self.sheet1.write(0, num, titles[num])
            for row in range(len(products)):
                for col in range(6):
                    self.sheet1.write(row + 1 + (len(self.productlist) - len(products)), col, products[row][col])
            self.workbook.save('Workbook.xls')
            print('创建execel完成!')
    

    页面数据的获取是通过循环来进行获取的,可以设置一个最大页面

        def __search(self):
            """
            遍历每一页
            """
            for i in range(1, MAX_PAGE + 1):
                self.index_page(i)
            self.browser.close()
    

    我调试的过程中,我一般设置最大页面是10页,但是偶尔还是会出现等待加载超时的情况,暂时还没做处理,另外淘宝对于淘气值较低的账号好像审核较高些,我之前用一个淘气值400的账号登录,几次之后就开始出现滑块然后不能自动登录,但由于我的另一个淘宝的淘气值是在一千以上,所以即使有滑块也能通过自动登录。

    淘宝商品列表的爬取是在上一篇的基础上做了进一步扩展,关于登录可以参考:淘宝爬虫之自动登录
    本篇文章具体实现可以参考GitHub:爬取淘宝商品列表
    这篇文章主要参考崔庆才的: [Python3网络爬虫开发实战] 7.4-使用Selenium爬取淘宝商品
    ,博客里面也有很多文章值得学习。很多地方可能写的不够完善,欢迎探讨指正。

    相关文章

      网友评论

        本文标题:爬取淘宝商品列表

        本文链接:https://www.haomeiwen.com/subject/frvpeqtx.html