淘宝商品比价定向爬虫-Python网络爬虫与信息提取-北京理工大学嵩天教授

功能描述

  • 目标:获取淘宝搜索页面的信息,提取其中的商品名称和价格;
  • 理解:淘宝的搜索接口、翻页的处理;
    以课程中的搜索书包为例,对应的url如下:
    (1)起始页;
    (2)第二页:最后的s=44;
    (3)第三页:最后的s=88;
    可见每一个页面最后的s是44的倍数,对应每页显示44个商品;
  • 技术路线:requests-bs4-re;

程序的结构设计

  • 提交商品搜索请求,循环获取页面;
  • 对于每个页面,提取商品名称和价格等信息;
  • 将信息输出到屏幕上;

代码实现

  • 获取页面html文本
def getHTMLText(url):
    try:
        kv = {
     'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Mobile Safari/537.36 Edg/88.0.705.56',
              'cookie':'t=deddd23bfe04ab15164c019112784f9c; cna=XK5LGA4m50ECAd9oJkUtgm7I; thw=cn; xlly_s=1; sgcookie=E10023Obh9wH5AWdx%2Fe7n3gl%2FZI8apXzKIErFStQ5NUCq3%2F9UYrF%2B7lI%2BN967STMEIBmunpgKuAgs%2B02R1E2Kb3%2Fkw%3D%3D; uc3=vt3=F8dCuAc7kVV3cGO6UpE%3D&lg2=V32FPkk%2Fw0dUvg%3D%3D&id2=UNDWqz%2BW1PBoCg%3D%3D&nk2=py2IFhkItJJhwQ%3D%3D; lgc=%5Cu817B%5Cu817Bninini; uc4=nk4=0%40pRuis6%2BJh76xIPKDeKEOvEm93LEw&id4=0%40UgcmAb1TDKQ0hqLa4CLaoKQH3sSr; tracknick=%5Cu817B%5Cu817Bninini; _cc_=VT5L2FSpdA%3D%3D; enc=b55neMOC4mLe80JhgcOCMv3RRT%2Bgd3Jr7BRuLm6yYbHBY8aIqO087t71RRsn5OJVY5LN5b14hUpuCT7xM55pmw%3D%3D; hng=CN%7Czh-CN%7CCNY%7C156; mt=ci=33_1; _m_h5_tk=7c2d3c2da0eba4f0ca62c06fcb13554f_1612439064793; _m_h5_tk_enc=927252cd80fc17adb09f49a138ecf921; _tb_token_=f350d8e59407; cookie2=1421470cd5225edfac39704d33d8a443; uc1=cookie14=Uoe1gB%2B9CAku%2Fg%3D%3D; JSESSIONID=E33478209544434CF08265F8EEE8CD73; alitrackid=www.taobao.com; lastalitrackid=www.taobao.com; l=eBEIV2fnjPZvYtyBBOfaourza779sIRbouPzaNbMiOCP_7fp5jscW6MM9K89CnGVh6xpR3r5KjjyBIBeqIv4n5U62j-la_Dqn; isg=BJ2dqTl0oSecwUULWgIzSNpErHmXutEMwxTFdV9i2_QjFrxIJwre3AiERAoQ0OnE; tfstk=cnZcBujlRruj-E3uRiibL7WzC6QRZC_qGlrz4ueHtAhmOXrPiQYy8Z9AEjBiEF1..'
              }
        r = requests.get(url, headers=kv, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        ptint("网页获取失败")

  • 注意:由于淘宝采取了反爬虫机制,所以我们可以先登录自己的账号后再来模仿浏览器进行访问爬取;
    登录后搜索“书包”,查看自己的cookie(按Fn+F12-网络-刷新页面-点击url-查找到cookie),复制粘贴到代码中,此处可参考查看网页的cookie和user-agent一文,如图所示:
    淘宝商品比价定向爬虫-Python网络爬虫与信息提取-北京理工大学嵩天教授_第1张图片
    cookie比较容易失效,访问多次后就需要滑动验证,获取新的cookie并修改到代码中。
  • 对每一个页面进行解析
    可通过搜索对应的价格、商品名称、发货地址获取其位置,并可写出对应的正则表达式,如图所示:淘宝商品比价定向爬虫-Python网络爬虫与信息提取-北京理工大学嵩天教授_第2张图片淘宝商品比价定向爬虫-Python网络爬虫与信息提取-北京理工大学嵩天教授_第3张图片
    在这里插入图片描述
def parsePage(ilt,html):
    try:
        re1 = re.compile(r'\"view_price\"\:\"[\d\.]*\"')  # 编译商品价格正则表达式
        re2 = re.compile(r'\"raw_title\"\:\".*?\"')       # 编译商品名称正则表达式
        re3 = re.compile(r'\"item_loc\"\:\".*?\"')        # 编译商品位置正则表达式
        plt = re1.findall(html)
        tlt = re2.findall(html)
        llt = re3.findall(html)
        # plt = re.findall(r'\"view_price\"\:\"[\d\.]*\"', html) #将商品信息保存在plt中 "view_price":"134.00"
        # tlt = re.findall(r'\"raw_title\"\:\".*?\"', html)      #最小匹配商品名称 "raw_title":"书包女韩版原宿ulzzang高中大学生背包大容"
        # llt = re.findall(r'\"item_loc\"\:\".*?\"', html)       #最小匹配商品地址 "item_loc":"江苏 连云港"
        for i in range(len(plt)):
            price = eval(plt[i].split(':')[1])     #以:为分隔符,只获得[1]位置的商品的价格数字
            title = eval(tlt[i].split(':')[1])     #以:为分隔符,只获得[1]位置的商品的名称
            location = eval(llt[i].split(':')[1])  # 以:为分隔符,只获得[1]位置的商品的位置
            ilt.append([price,location,title])     #将price和title存入ilt列表中
    except:
        print("网页解析失败")

  • 信息输出
def printGoodsList(ilt):
    try:
        tplt = "{0:4}\t{1:^8}\t{2:^12}\t{3:{4}^40}"   # 格式
        print(tplt.format("序号", "价格", "发货位置","商品名称",chr(12288)))  # 打印表头
        count = 0   # 计数器
        for g in ilt:
            count = count + 1
            print(tplt.format(count, g[0], g[1],g[2],chr(12288)))
    except:
        print("输出失败")

  • 注意:使用chr(12288)填充中文空格以保证表格的对齐;
    此处可参考Python 的 format 格式化输出一文;
  • 主函数
def main():
    goods = '书包'
    depth = 2   #爬取深度
    start_url = 'https://s.taobao.com/search?q=' + goods
    infoList = []
    for i in range(depth):
        try:
            url = start_url + '&s=' + str(44*i)    #构建不同页面的url链接
            html = getHTMLText(url)
            parsePage(infoList,html)
        except:
            continue
    printGoodsList(infoList)

  • 总代码
import requests
import re

#获得页面的函数
def getHTMLText(url):
    try:
        kv = {
     'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Mobile Safari/537.36 Edg/88.0.705.56',
              'cookie':'t=deddd23bfe04ab15164c019112784f9c; cna=XK5LGA4m50ECAd9oJkUtgm7I; thw=cn; sgcookie=E10023Obh9wH5AWdx%2Fe7n3gl%2FZI8apXzKIErFStQ5NUCq3%2F9UYrF%2B7lI%2BN967STMEIBmunpgKuAgs%2B02R1E2Kb3%2Fkw%3D%3D; uc3=vt3=F8dCuAc7kVV3cGO6UpE%3D&lg2=V32FPkk%2Fw0dUvg%3D%3D&id2=UNDWqz%2BW1PBoCg%3D%3D&nk2=py2IFhkItJJhwQ%3D%3D; lgc=%5Cu817B%5Cu817Bninini; uc4=nk4=0%40pRuis6%2BJh76xIPKDeKEOvEm93LEw&id4=0%40UgcmAb1TDKQ0hqLa4CLaoKQH3sSr; tracknick=%5Cu817B%5Cu817Bninini; _cc_=VT5L2FSpdA%3D%3D; enc=b55neMOC4mLe80JhgcOCMv3RRT%2Bgd3Jr7BRuLm6yYbHBY8aIqO087t71RRsn5OJVY5LN5b14hUpuCT7xM55pmw%3D%3D; hng=CN%7Czh-CN%7CCNY%7C156; mt=ci=33_1; _m_h5_tk=aff79b9da27bfc34bf439ff14e19bd1c_1612686597552; _m_h5_tk_enc=df797590926f146a4442f321b1b38af9; xlly_s=1; _tb_token_=55eee656e7a35; cookie2=16e4068d824ad34232f28fd308e84bd5; uc1=cookie14=Uoe1gB37P0vuag%3D%3D; alitrackid=www.taobao.com; lastalitrackid=www.taobao.com; JSESSIONID=08B5DD09E5FA9256717C371A6AB7E949; l=eBEIV2fnjPZvYh-BBOfanurza77OSIRYouPzaNbMiOCP_ofH5x_fW6MhRjTMC3GRh6D9R3l29V7YBeYBq6fnnxv92j-la_kmn; tfstk=clohB3tMl2zBkbailHZI3vMikbYAayS0Gr4ZbchJsFFo7gc3Lsml7Z8Cp6P6Ihb5.; isg=BLq60wePjipC0wLCYTPs0QGlC-Dcaz5FzyGrdsSzZs0Yt1rxrPuOVYCNA0VrIbbd'
              }
        r = requests.get(url, headers=kv, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        ptint("网页获取失败")

#对每一个页面进行解析
def parsePage(ilt,html):
    try:
        re1 = re.compile(r'\"view_price\"\:\"[\d\.]*\"')  # 编译商品价格正则表达式
        re2 = re.compile(r'\"raw_title\"\:\".*?\"')       # 编译商品名称正则表达式
        re3 = re.compile(r'\"item_loc\"\:\".*?\"')        # 编译商品位置正则表达式
        plt = re1.findall(html)
        tlt = re2.findall(html)
        llt = re3.findall(html)
        # plt = re.findall(r'\"view_price\"\:\"[\d\.]*\"', html) #将商品信息保存在plt中 "view_price":"134.00"
        # tlt = re.findall(r'\"raw_title\"\:\".*?\"', html)      #最小匹配商品名称 "raw_title":"书包女韩版原宿ulzzang高中大学生背包大容"
        # llt = re.findall(r'\"item_loc\"\:\".*?\"', html)       #最小匹配商品地址 "item_loc":"江苏 连云港"
        for i in range(len(plt)):
            price = eval(plt[i].split(':')[1])   #以:为分隔符,只获得[1]位置的商品的价格数字
            title = eval(tlt[i].split(':')[1])   #以:为分隔符,只获得[1]位置的商品的名称
            location = eval(llt[i].split(':')[1])   # 以:为分隔符,只获得[1]位置的商品的位置
            ilt.append([price,location,title])   #将price和title存入ilt列表中
    except:
        print("网页解析失败")

#信息输出
def printGoodsList(ilt):
    try:
        tplt = "{0:4}\t{1:^8}\t{2:^12}\t{3:{4}^40}"  # 格式
        print(tplt.format("序号", "价格", "发货位置","商品名称",chr(12288)))  # 打印表头
        count = 0  # 计数器
        for g in ilt:
            count = count + 1
            print(tplt.format(count, g[0], g[1],g[2],chr(12288)))
    except:
        print("输出失败")

#主函数
def main():
    goods = '书包'
    depth = 2     #爬取深度
    start_url = 'https://s.taobao.com/search?q=' + goods
    infoList = []
    for i in range(depth):
        try:
            url = start_url + '&s=' + str(44*i)      #构建不同页面的url链接
            html = getHTMLText(url)
            parsePage(infoList,html)
        except:
            continue
    printGoodsList(infoList)


if __name__ == '__main__':
    main()
  • 爬取结果
    所获得的信息显示出来了,如下所示:
序号  	   价格   	    发货位置    	                  商品名称                  
   1	 179.00 	   广东 广州    	       mracehomme可爱手提日本双肩包女韩版大学生        
   2	 699.00 	   福建 泉州    	   FILA斐乐童装男女童双肩包2020年冬季新款小学生书包初中儿童背包   
   3	 379.00 	   福建 泉州    	   FILA斐乐男童女童书包小学生背包2020年秋冬季新款时尚儿童双肩包   
   4	 39.80  	   河北 保定    	 ins书包女韩版原宿ulzzang高中大学生简约百搭2020新款双肩包背包  
   5	 39.90  	   河北 保定    	  ins书包女韩版原宿ulzzang日系简约少女心学院风大学生双肩包背包   
   6	 129.00 	   浙江 嘉兴    	   KK剑桥树书包小学生男孩一二三到六年级儿童6-12岁男童双肩包减负    
   7	 288.00 	   广东 广州    	     欧洲站双肩包真皮男士背包旅游包时尚潮流大容量真皮书包电脑包      
   8	 265.00 	     上海     	    书包女韩版高中双肩包2021新款百搭初中学生校园大容量背包电脑包    
   9	 59.00  	     上海     	     双肩包男士大容量电脑旅行背包女时尚潮流大学生高中初中学生书包     
  10	 299.00 	   江苏 无锡    	CONVERSE匡威官方 Straight Edge休闲百搭双肩包实用书包10021138
  11	 438.00 	   浙江 杭州    	   荷兰Backcare小学生书包一二三到六年级男孩女儿童减负护脊超轻便   
  12	 148.00 	   广东 广州    	     旅行包男户外登山休闲超大容量旅游双肩书包出差背包女行李多功能     
  13	 298.00 	     上海     	    牛津布双肩包女2020新款韩版百搭时尚学生书包大容量旅行背包小包    
  14	 970.00 	   广东 深圳    	   Gaston Luga瑞典潮牌电脑双肩包男背包女大容量旅行包休闲书包   
  15	 438.00 	   广东 广州    	   backcare书包小学生一二三四五六年级男女孩儿童轻便减负护脊减压   
  16	 129.00 	   浙江 嘉兴    	   KK剑桥树书包小学生女孩一二三到六年级儿童双肩包护脊减负6-12岁    
  17	 129.00 	   浙江 嘉兴    	   KK树书包小学生女孩6-12岁儿童一二三到六年级女童双肩包护脊减负    
  18	 298.00 	   广东 广州    	     欧洲站双肩包真皮男士简约休闲时尚背包商务电脑旅行学生青年书包     
  19	 253.00 	   福建 厦门    	     牛津布背包电脑双肩包男出差旅行包简约轻便潮流高中生大学生书包     
  20	 69.00  	   湖南 邵阳    	    新款书包小学生女童一二三到六年级护脊儿童2020女孩韩版轻便减负    

到此,整个爬取就结束了。

你可能感兴趣的:(python,正则表达式,爬虫)