爬取淘宝商品列表

在解决了淘宝登录问题以后就开始进行淘宝商品的爬取,住要是利用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爬取淘宝商品
,博客里面也有很多文章值得学习。很多地方可能写的不够完善,欢迎探讨指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 本文作者:千花坊 不知道你们有没有这种感觉 我从不觉得这世界上会有对自己喜欢的东西不怀有强烈占有欲的人,因为喜欢,...
    的卡夫卡的阅读 251评论 0 0
  • VIM 什么是vim 所有的Unix like系统都会内置vi文本编辑器,其他的文本编辑器则不一定会存在。vim具...
    Mizuka阅读 303评论 0 3
  • 本周作业:瑜伽可以提高我们的觉知度,要学会改变我们的行为模式。 1.早饭后愉快的带二宝去送大宝,一路和老大谈话转移...
    平安小娥子阅读 162评论 0 0
  • 我的外公已年近80岁了,由于我们生活的城市距离远,只有逢年过节,我们才同父母回去探亲… 前段时间,外公生病了,病的...
    攀岩的蜗牛111阅读 1,283评论 1 2