GlidedSky爬虫学习探索之旅(三)

题目四:爬虫-CSS反爬

在这里插入图片描述
在这里插入图片描述

分析题目:

(一)界面显示的117,在源码中是171。查看171元素对应的css源码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到,第一个1中left没有赋值。第二个7中left的值为1em,第三个1中left的值为-1em。
对【 1 7 1】进行移位,7的index+1em,第三个1的index-1em,结果为【1 1 7】,即为界面显示的数字。

(二)界面上显示141,源码中为6114。查看6114元素对应的css源码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
【 6 1 1 4 】,对6的index+1em-1em,对第一个1的index+2em,对第二个1的index-1em,对4的index-1em。【 6 1 4 1】,即后三位为界面显示的数值。对移位结果仅取后三位即可。

(三)界面上显示182,源码显示<div class=“txYyv21NCh”>:before</div>。
在这里插入图片描述
直接取得对应before的content内容即为界面上显示的内容。

从上面三个的分析可以总结出编码规律:
1.长度为3的,字体的顺序被打乱,根据left的赋值,调整位置即可。
2.长度为4的,基于1中的方法得到结果后,取得后面三位数值即为界面显示的值。
3.长度小于3的,直接在元素对应的before的content中找到该数值。

最开始的我,也以为分析完上面这些规律后,就可以正确的解答题目了,但跑完一次后,把答案提交,发现还是错误的。然后反复调试后,发现编码规律没那么简单。遗漏了以下场景:

(四)界面上显示116,源码显示<div class=“col-md-1”><div class=“eYcN0stlEG”>8</div> <div class=“CJZPE1XcUe”>:before</div></div>。
在这里插入图片描述
在这里插入图片描述
【8 116】,对8的index-1em会出现<0的现象,需要考虑index越界的问题。

(五)界面上显示97,源码显示997。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
根据以上分析,该结果的获取过程中,同时还需要关注margin-right是否具有赋值。

所以编码规律还需要注意:
4.index是否越界。
5.同时需要关注margin-right是否具有赋值。

根据以上总结的规律,进一步就是编写代码解题啦(代码中存在部分冗余代码,可以进一步优化哦~)

#coding:utf-8  CSS反爬
import re
import asyncio,pyppeteer
from lxml import etree

class testMl:

    def __init__(self):
        self.total_num = 0
    def detail_parse(self,div_html, response_str):
        """
        :param div_html: 传进来的div[@class='col-md-1']
        :param response_str: 该网页的elements内容,也就是response.text
        :return:None
        """
        # 获取div[@class='col-md-1']下的所有div标签
        div_list = div_html.xpath("//div//div")
        # todo:1.对于div_list长度为3以下的
        # 就是使用伪元素选择器
        if len(div_list) < 3:
            number = [0]*len(div_list)
            for i in range(len(div_list)):
                text = div_list[i].xpath(".//text()")
                if not text:
                    class_name = div_list[i].xpath(".//@class")[0]
                    #() 是为了提取匹配的字符串
                    num = re.findall(r"\.{}\:before\s*.*?\s*content\:\"(\d*)\"".format(class_name), response_str, re.S)[0]
                    self.total_num += int(num)
                    # print(num, "总数", self.total_num)
                else:
                    class_name = div_list[i].xpath(".//@class")[0]
                    data = div_list[i].xpath(".//text()")[0]
                    left = re.findall(r"\.{}\s.*?\sleft\:(.*?)em".format(class_name), response_str)
                    margin_right = re.findall(r"\.{}\s.*?\smargin-right\:(.*?)em".format(class_name), response_str)
                    if not left and not margin_right:
                        # 如果left和margin_right为空,表名位置不需要调整
                        number[i] = data
                    # 否则就需要调整位置
                    else:
                        index = 0
                        if left:
                            index = i + int(left[0])
                        if margin_right:
                            index = i + int(margin_right[0])
                        if index >= 0 :#index大于等于0的时候才赋值
                            number[index] = data
            num = ''
            for j in range(len(number)):
                num += str(number[j])
            if int(num) !=0:
                self.total_num += int(num)
                # print(num, "总数", self.total_num)


        # todo:2.对于div_list长度大于等于3的
        # 长度为4就是其中有个div不显示,长度为3就是div标签数据显示顺序打乱
        else:
            if len(div_list) == 4:
                div_list = div_list[1:]#只取后三位
            number = [0]*len(div_list)
            for i in range(0, len(div_list)):
                div = div_list[i]
                class_name = div.xpath(".//@class")[0]
                data = div.xpath(".//text()")[0]
                left = re.findall(r"\.{}\s.*?\sleft\:(.*?)em".format(class_name), response_str)
                margin_right = re.findall(r"\.{}\s.*?\smargin-right\:(.*?)em".format(class_name), response_str)
                if not left and not margin_right:
                    # 如果left和margin_right为空,表名位置不需要调整
                    number[i] = data
                # 否则就需要调整位置
                else:
                    index = 0
                    if left:
                        index = i + int(left[0])
                    if margin_right:
                        index = i + int(margin_right[0])
                    if index >= 0:
                        number[index] = data
            num = ''
            for k in range(len(number)):
                num += str(number[k])
            self.total_num += int(num)
            # print(num, "总数", self.total_num)

    def print_total(self):
        print("总数", self.total_num)


async def main():
    brower = await  pyppeteer.launch(headless=False)
    page = await brower.newPage()
    Ml = testMl()
    await page.setUserAgent(
        'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0')
    await page.setJavaScriptEnabled(enabled=True)
    await page.evaluate(
        '''() =>{ Object.defineProperties(navigator,{ webdriver:{ get: () => false } }) }''')
    await page.goto("http://www.glidedsky.com/level/web/crawler-css-puzzle-1")
    # print(await page.content())
    address = "123456789@qq.com"
    passwd = "******"
    await page.type('#email', address)
    await page.type("#password", passwd)
    button = (await page.xpath('//*[@id="app"]/main/div[1]/div/div/div/div[2]/form/div[4]/div/button'))[0]
    await button.click()
    await asyncio.sleep(2.0)
    for i in range(1,1001):
        await page.goto("http://www.glidedsky.com/level/web/crawler-css-puzzle-1?page={0}".format(i))
        # print(i)
        content = await page.content()
        tree_content = etree.HTML(content)
        for k in range(1,13):
            col_md = tree_content.xpath('//*[@id="app"]/main/div[1]/div/div/div/div[{0}]'.format(k))[0]
            col_md = etree.tostring(col_md)
            col_md_html = etree.HTML(col_md)
            # print(col_md_html)
            Ml.detail_parse(col_md_html,content)
        # await asyncio.sleep(2.0)
    await brower.close()
    Ml.print_total()


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

总的来说,反爬的技巧在于分析编码的规律,找到规律,也就能够解题了~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

merlin’s girl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值