zoukankan      html  css  js  c++  java
  • (反反爬虫)X车之家车型配置页的字体反爬

      唉,说句实在话,最近些爬虫也写的比较多了,经常爬一些没有反爬措施,或者反爬只停留在验证cookies、UA、referer的网站真的没太多乐趣。前端时间在知乎上看见了一个专栏,反反爬虫系列,于是乎也就入了坑,目前除了第二个之外全部都跟着作者的思路复现了代码,收获真的挺多的。话说python爬虫在知乎上的活跃度真的挺高的,经常有一些前辈、大牛在上面分享经验、教程。在知乎上查看、学习、讨论、复现他们的代码,很方便而且收获挺多!

      好了,废话也不多说了,开始今天的主题把。汽车之家汽车参数配置的爬虫。

      其实刚开始看完这篇文章我是懵逼的,懵逼的地方不在于解析JS获取真实数据,而是在于这句话,

       按照index替换就行?我将通过JS拿到的数据认真的同网页进行了比对,怎么也找不到这返回的数据跟网页有什么相似的地方,无奈最后网上各种找,终于找到了一个博主写的文章了,运行了之后成功的拿到了数据,心中很是欣喜,然后也终于明白了按照index替换就行这句话的含义。

      下面我讲我写的代码贴出来,当然了,这段代码只是为了跑通并拿到数据,并没有对其进行结构化封装。

      1 import re
      2 import os
      3 import json
      4 
      5 import requests
      6 import xlwt
      7 from selenium import webdriver
      8 
      9 
     10 url = "https://car.autohome.com.cn/config/series/2357.html#pvareaid=3454437"
     11 headers = {
     12     "User-agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
     13                   "Chrome/71.0.3578.98 Safari/537.36"
     14 }
     15 # 运行JS的DOM
     16 DOM = ("var rules = '2';"
     17        "var document = {};"
     18        "function getRules(){return rules}"
     19        "document.createElement = function() {"
     20        "      return {"
     21        "              sheet: {"
     22        "                      insertRule: function(rule, i) {"
     23        "                              if (rules.length == 0) {"
     24        "                                      rules = rule;"
     25        "                              } else {"
     26        "                                      rules = rules + '#' + rule;"
     27        "                              }"
     28        "                      }"
     29        "              }"
     30        "      }"
     31        "};"
     32        "document.querySelectorAll = function() {"
     33        "      return {};"
     34        "};"
     35        "document.head = {};"
     36        "document.head.appendChild = function() {};"
     37 
     38        "var window = {};"
     39        "window.decodeURIComponent = decodeURIComponent;")
     40 
     41 response = requests.get(url=url, headers=headers, timeout=10)
     42 # print(response.content.decode("utf-8"))
     43 html = response.content.decode("utf-8")
     44 
     45 # 匹配汽车的参数
     46 car_info = ""
     47 config = re.search("var config = (.*?)};", html, re.S)       # 车的参数
     48 option = re.search("var option = (.*?)};", html, re.S)   # 主被动安全装备
     49 bag = re.search("var bag = (.*?)};", html, re.S)             # 选装包
     50 js_list = re.findall('((function([a-zA-Z]{2}.*?_).*?(document);)', html)
     51 # 拼接车型的所有参数car_info
     52 if config and option and bag:
     53     car_info = car_info + config.group(0) + option.group(0) + bag.group(0)
     54 # print(car_info)
     55 
     56 # 封装JS成本地文件通过selenium执行,得到true_text
     57 for item in js_list:
     58     DOM = DOM + item
     59 html_type = "<html><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /><head></head><body>    <script type='text/javascript'>"
     60 js = html_type + DOM + " document.write(rules)</script></body></html>"    # 待执行的JS字符串
     61 os.makedirs("D:\test11")
     62 with open("D:\test11\asd.html", "w", encoding="utf-8") as f:
     63     f.write(js)
     64 browser = webdriver.Chrome(executable_path="D:chromedrivechromedriver.exe")
     65 browser.get("file://D:/test11/asd.html")
     66 true_text = browser.find_element_by_tag_name('body').text   
     67 # print(true_text)
     68 
     69 span_list = re.findall("<span(.*?)></span>", car_info)    # 匹配车辆参数中所有的span标签
     70 
     71 # 按照span标签与true_text中的关键字进行替换
     72 for span in span_list:
     73     info = re.search("'(.*?)'", span)
     74     if info:
     75         class_info = str(info.group(1)) + "::before { content:(.*?)}"                   #
     76         content = re.search(class_info, true_text).group(1)                             # 匹配到的字体
     77         car_info = car_info.replace(str("<span class='" + info.group(1) + "'></span>"),
     78                                     re.search(""(.*?)"", content).group(1))
     79 # print(car_info)
     80 
     81 # 持久化
     82 car_item = {}
     83 config = re.search("var config = (.*?);", car_info).group(1)
     84 option = re.search("var option = (.*?);var", car_info).group(1)
     85 bag = re.search("var bag = (.*?);", car_info).group(1)
     86 
     87 config_re = json.loads(config)
     88 option_re = json.loads(option)
     89 bag_re = json.loads(bag)
     90 
     91 config_item = config_re['result']['paramtypeitems'][0]['paramitems']
     92 option_item = option_re['result']['configtypeitems'][0]['configitems']
     93 bag_item = bag_re['result']['bagtypeitems'][0]['bagitems']
     94 
     95 for car in config_item:
     96     car_item[car['name']] = []
     97     for value in car['valueitems']:
     98         car_item[car['name']].append(value['value'])
     99 
    100 for car in option_item:
    101     car_item[car['name']] = []
    102     for value in car['valueitems']:
    103         car_item[car['name']].append(value['value'])
    104 
    105 for car in bag_item[0]['valueitems']:
    106     car_item[car['name']] = []
    107     car_item[car['name']].append(car['bagid'])
    108     car_item[car['name']].append(car['pricedesc'])
    109     car_item[car['name']].append(car['description'])
    110 
    111 # 生成表格
    112 workbook = xlwt.Workbook(encoding='ascii')  # 创建一个文件
    113 worksheet = workbook.add_sheet('汽车之家')  # 创建一个表
    114 cols = 0
    115 start_row = 0
    116 
    117 for co in car_item:
    118     cols = cols + 1
    119     worksheet.write(start_row, cols, co)  # 在第0(一)行写入车的配置信息
    120 
    121 end_row_num = start_row + len(car_item['车型名称'])  # 车辆款式记录数
    122 for row in range(start_row, end_row_num):
    123     col_num = 0  # 列数
    124     row += 1
    125     for col in car_item:
    126         col_num = col_num + 1
    127         worksheet.write(row, col_num, str(car_item[col][row - 1]))
    128 
    129 workbook.save('d:\test.xls')
    View Code

       ok,在强调一遍,这段代码只是为了跑通并拿到数据,并没有对其进行结构化封装。

      最后感谢这位博主:https://www.cnblogs.com/kangz/p/10011348.html

    通过这段时间跟着知乎的专栏的学习,明显看见了自己的不足!一定要沉着冷静的去分析、思考,网站对API进行了加密,一定能够解密!

  • 相关阅读:
    python 的基础 学习 第六天 基础数据类型的操作方法 字典
    python 的基础 学习 第五天 基础数据类型的操作方法
    python 的基础 学习 第四天 基础数据类型
    ASP.NET MVC 入门8、ModelState与数据验证
    ASP.NET MVC 入门7、Hellper与数据的提交与绑定
    ASP.NET MVC 入门6、TempData
    ASP.NET MVC 入门5、View与ViewData
    ASP.NET MVC 入门4、Controller与Action
    ASP.NET MVC 入门3、Routing
    ASP.NET MVC 入门2、项目的目录结构与核心的DLL
  • 原文地址:https://www.cnblogs.com/pontoon/p/10459471.html
Copyright © 2011-2022 走看看