• Python爬虫之selenium爬虫,模拟浏览器爬取天猫信息


    由于工作需要,需要提取到天猫400个指定商品页面中指定的信息,于是有了这个爬虫。这是一个使用 selenium 爬取天猫商品信息的爬虫,虽然功能单一,但是也算是 selenium 爬虫的基本用法了。

    源码展示

     1 from selenium import webdriver
     2 from selenium.webdriver.common.by import By
     3 from selenium.webdriver.support.ui import WebDriverWait
     4 from selenium.webdriver.support import expected_conditions as EC
     5 from selenium.common.exceptions import TimeoutException
     6 import csv
     7 import time
     8 
     9 class TM_itemdetail(object):
    10     def __init__(self,readname='ids.txt',savename='info.csv'):
    11         '''传入2个参数,分别是读取ID的文本名称和保存信息的表格名称,给予默认值'''
    12         self.readname = readname
    13         self.savename = savename
    14         self.driver = webdriver.Chrome()
    15         self.driver.maximize_window()
    16         # 设置一个智能等待
    17         self.waiter = WebDriverWait(self.driver,5)
    18         self.get_csv()
    19 
    20     def get_csv(self):
    21         '''创建一个表格,并且给表格添加标题行'''
    22         with open(self.savename,'w',newline='') as f:
    23             fieldnames = ['id','info']
    24             writer = csv.DictWriter(f,fieldnames=fieldnames)
    25             writer.writeheader()
    26 
    27     def write_info(self,info_dic):
    28         '''写入单个信息,传入的参数是一个字典,字典的key跟表格的标题对应'''
    29         with open(self.savename,'a',newline='') as f:
    30             fieldnames = ['id', 'info']
    31             writer = csv.DictWriter(f, fieldnames=fieldnames)
    32             writer.writerow(info_dic)
    33 
    34     def get_ids(self):
    35         '''读取文本的ID,形成一个列表'''
    36         with open(self.readname,'r') as f:
    37             lines = f.readlines()
    38         ids = [k.replace('
    ','').strip() for k in lines]
    39         return ids
    40 
    41     def get_info(self,id):
    42         '''爬虫的主要操作,模拟打开浏览器,找到信息的标签,提取后写入表格'''
    43         dic = {}
    44         url = 'https://detail.tmall.com/item.htm?id={}'.format(id)
    45         self.driver.get(url)
    46         # html = self.driver.page_source
    47         # print(html)
    48         try:
    49             location = self.waiter.until(
    50                 EC.presence_of_element_located((By.XPATH,'//li[@class="J_step4Time"]'))
    51             )
    52             info = location.text.strip()
    53             dic['id'] = id
    54             dic['info'] = info if info else '信息为空白'
    55             self.write_info(dic)
    56         except TimeoutException as e:
    57             print(e)
    58             dic['id'] = id
    59             dic['info'] = '{}超时,未找到信息'.format(e).strip()
    60             self.write_info(dic)
    61 
    62     def main(self):
    63         '''主函数,循环爬取,并打印相应的操作过程'''
    64         ids = self.get_ids()
    65         counter = len(ids)
    66         i = 1
    67         for id in ids:
    68             self.get_info(id)
    69             print('总计{}个,已经爬取{}个'.format(counter,i))
    70             i += 1
    71 
    72 
    73 if __name__ == '__main__':
    74     start = time.time()
    75     tm = TM_itemdetail()
    76     tm.main()
    77     tm.driver.close()
    78     end = time.time()
    79     print('运行结束,总耗时:{:.2f}秒'.format(end-start))

    源码解析

    这个爬虫主要由三个步骤构成:

    1. 读取文本中商品ID
    2. 循环爬取每个商品的信息
    3. 将信息保存到csv表格中

    读取文本中的信息

    由于是爬取给定的商品ID的宝贝的信息,所以需要一份包含商品ID的文本,文本中每行放入一个商品ID即可。

    然后使用 Python 内置的方法,读取所有的商品ID并形成一个列表返回即可,这个过程可以封装到一个函数中,也即是下面这个:

    def get_ids(self):
        '''读取文本的ID,形成一个列表'''
        with open(self.readname,'r') as f:
            lines = f.readlines()
        ids = [k.replace('
    ','').strip() for k in lines]
        return ids

    这个函数看似没有传入参数,实际上因为是类的函数,所以有个参数是使用的类的属性,也就是文本的名称 self.readname。文件的读写可以使用 with...as... 语句,这种操作比较简洁方便。

    爬取页面信息

    下面截图中红色部分即使要提取的信息部分:

    本来想着可以直接找到 URL 构造的规律去使用 requests 来爬的,但是最终还是遇到了难度,于是没有办法,只好祭出 selenium 这个大杀器!

    selenium 爬虫的本质就是模拟浏览器的操作,所以这个爬虫很简单,只需要模拟浏览器打开以下网页,然后找到自己要的信息,提取就行了。

    具体代码也封装到了一个函数中,这个函数需要传递一个参数,也就是一个商品ID,用来构成 URL 以便爬虫使用。

    def get_info(self,id):
        '''爬虫的主要操作,模拟打开浏览器,找到信息的标签,提取后写入表格'''
        dic = {}
        url = 'https://detail.tmall.com/item.htm?id={}'.format(id)
        self.driver.get(url)
        # html = self.driver.page_source
        # print(html)
        try:
            location = self.waiter.until(
                EC.presence_of_element_located((By.XPATH,'//li[@class="J_step4Time"]'))
            )
            info = location.text.strip()
            dic['id'] = id
            dic['info'] = info if info else '信息为空白'
            self.write_info(dic)
        except TimeoutException as e:
            print(e)
            dic['id'] = id
            dic['info'] = '{}超时,未找到信息'.format(e).strip()
            self.write_info(dic)

    这个函数主要进行的操作流程为:

    1. 打开浏览器
    2. 输入一个 URL
    3. 等待页面刷新之后查找信息标签
    4. 提取指定信息,然后使用封装好的函数写入表格

    其中最重要的步骤是提取信息的过程,这个使用了智能等待,也就是设定一个超时,然后浏览器会在这个超时的时间内智能的多次查找指定的信息,直到找到信息就进行下一步,否则继续刷新页面查找,直到超时时间到达报错。

    保存信息到表格

    信息已经提取,就需要保存起来,因为这个爬虫是工作需要,而且量也比较小,所以最佳的保存信息的方式就是 CSV 的表格形式了,直接使用 Python 自带的 csv 模块就可以。

    信息保存分为2个部分:

    • 在程序运行的最初,创建一个表格,并且给表格写入标题
    • 在每次爬完一个页面,就在表格中写入一条信息

    所以,写入表格的代码其实就是分成2个部分来的。

    第一部分:

    def get_csv(self):
        '''创建一个表格,并且给表格添加标题行'''
        with open(self.savename,'w',newline='') as f:
            fieldnames = ['id','info']
            writer = csv.DictWriter(f,fieldnames=fieldnames)
            writer.writeheader()

    这个部分创建了一个表格,并且可以看到,在爬虫类的的初始化中,已经运行了这个函数,也就是说,在爬虫创建的时候,就创建了一个表格。

    self.get_csv()

    第二部分:

    1 def write_info(self,info_dic):
    2     '''写入单个信息,传入的参数是一个字典,字典的key跟表格的标题对应'''
    3     with open(self.savename,'a',newline='') as f:
    4         fieldnames = ['id', 'info']
    5         writer = csv.DictWriter(f, fieldnames=fieldnames)
    6         writer.writerow(info_dic)

    这个函数就是封装的写入信息,需要传入一个参数,也就是已经提取到的信息,这个信息需要写成字典的格式,因为在表格中已经创建了标题,所以可以直接使用标题的值来作为字典的 key。

    循环爬取

    最后,将整个爬虫的逻辑封装到一个主函数 main() 中即可,并且,为了可以及时看到爬虫的运行进度,可以在控制台中打印爬虫的进度信息。

    1 def main(self):
    2     '''主函数,循环爬取,并打印相应的操作过程'''
    3     ids = self.get_ids()
    4     counter = len(ids)
    5     i = 1
    6     for id in ids:
    7         self.get_info(id)
    8         print('总计{}个,已经爬取{}个'.format(counter,i))
    9         i += 1

    后记:不得不说,Python真的是个神器,很多需要花大量的时间去重复操作的一个事情,只需要花一点点时间写一个爬虫代码就能做到。

    所以,那句话怎么说来着,人生苦短,快用 Python !

    原创文章,装载请注明出处,文章内容来自 http://www.stopfollow.com/article/selenium-crawler-get-tmall-information/

      

  • 相关阅读:
    python's eithteenth day for me 面向对象——命名空间
    python's seventeenth day for me 面向对象
    python's sixteenth day for me 员工信息表
    python's fifteenth day for me 递归函数
    python's fourteenth day for me 内置函数
    用装饰器做一个登陆功能(进阶):
    装饰器 为多个函数加上认证功能(账号密码来源于文件),要求只要登陆成功一次,后续函数则无需登陆。
    python's thirteenth day for me 迭代器 生成器
    php函数
    php日期格式
  • 原文地址:https://www.cnblogs.com/gopythoner/p/7735379.html
Copyright © 2020-2023  润新知