SVG映射反爬虫

SVG映射反爬虫,是将关键的数字用 `<d></d> `去替换了。只要找到映射关系就好了。

目标网址:http://www.porters.vip/confusion/food.html

适合映射少

结果展示:

 

代码:

import requests
from parsel import Selector
class SVGCrawler():
    def __init__(self):
        self.maps = {'vhk08k': 0, 'vhk6zl': 1, 'vhk9or': 2, 'vhkbvu': 4,
                     'vhk84t': 5, 'vhkqsc': 7, 'vhkjj4': 8, }
    def crawler(self):
        base_url = 'http://www.porters.vip/confusion/food.html'
        response = requests.get(base_url)
        self.xpath(response.text)
    def xpath(self, res):
        sel = Selector(res)
        title = sel.css('.title::text').extract_first().strip()
        phone = sel.css('.more>d::attr("class")').extract()
        print(title)
        print([self.maps.get(_) for _ in phone])
if __name__ == '__main__':
    svg = SVGCrawler()
    svg.crawler()

适合映射多

首先讲一下具体思路:

首先抓取css文件,匹配里面的特殊字符串、横纵坐标,放到列表待用。

抓取svg文件,获取 text 的所有行数据(包含横纵坐标)

遍历css的列表,根据y值,去匹配svg-text文件的具体行数,并将结果行返回

根据x的坐标,除以字体大小,就等于当前的字符串映射位于本行的位置

将 字符串、结果放入一个字典

爬取目标页面,获取里面的特殊字符串,返回列表,遍历列表,根据字典get方法取值、建立映射关系。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import requests, re
from parsel import Selector
class SVGCrawler():
    # 初始化svg、css、目标url的链接地址,初始化一个存放映射关系的字典
    def __init__(self):
        self.css_url = 'http://www.porters.vip/confusion/css/food.css'
        self.svg_url = 'http://www.porters.vip/confusion/font/food.svg'
        self.url = 'http://www.porters.vip/confusion/food.html'
        self.svg_dict = {}
    # 获取css对应的svg参数,添加进字典
    def generate_map(self):
        css_text = requests.get(self.css_url).text
        svg_text = requests.get(self.svg_url).text
        # 利用正则表达式获取 css 内包含的 特殊字符串、横、纵坐标
        pat = re.compile("\.(.*)\s\{\s+background: -(\d+)px -(\d+)px;\s+\}")
        css_list = re.findall(pat, css_text)
        # 获取 svg 所有的行数据
        svg_data = Selector(svg_text)
        texts = svg_data.xpath('//text')
        # 遍历 css_list 获取的 特殊字符串 ('vhkqsc', '288', '141')
        for _ in css_list:
            css_word, x, y = _[0], int(_[1]), int(_[2])
            # 根据css的y匹配对应的行,y值并不对应,但是svg的y值不可能小于css的y值
            # 所以我们只要保证 y <= svg的y,就可以,结果会有多个,我们只取第一个。
            y_text = [i.xpath('text()').extract() for i in texts
                      if y <= int(i.attrib.get('y'))][0][0]
            # 获取 svg 的 font-size
            font_size = re.search('font-size:(\d+)px;', svg_text).group(1)
            # x // 字体大小 = 坐标 ,因为可能会有余数,所以取整。
            positon = x // int(font_size)
            # 将结果更新到字典svg_dict:'vhk08k': 0
            self.svg_dict[_[0]] = y_text[positon]
    # 获取目标页的特殊字符串,将特殊字符根据上面字典进行映射
    def analysis(self):
        response = requests.get(self.url)
        sel = Selector(response.text)
        title = sel.css('.title::text').extract_first().strip()
        # 获取电话号码的 clss 属性值,返回的列表
        phone_list = sel.css('.more d::attr("class")').extract()
        print(title)
        # 遍历列表字符串,找到对应的值。
        for _ in phone_list:
            print(self.svg_dict.get(_, '-'), end='')
if __name__ == '__main__':
    svg = SVGCrawler()
    svg.generate_map()
    svg.analysis()

 

版权声明:
作者:hyzsj0106
链接:https://www.cxywy.com/?p=353
来源:程序员无垠
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
< <上一篇
下一篇>>
文章目录
关闭
目 录