zoukankan      html  css  js  c++  java
  • requests.post()

    控制台抓包

    打开方式几常用选项

    1、打开浏览器,F12打开控制台,找到Network选项卡
    2、控制台常用选项
       1、Network: 抓取网络数据包
            1、ALL: 抓取所有的网络数据包
            2、XHR:抓取异步加载的网络数据包
            3、JS : 抓取所有的JS文件
       2、Sources: 格式化输出并打断点调试JavaScript代码,助于分析爬虫中一些参数
       3、Console: 交互模式,可对JavaScript中的代码进行测试
    3、抓取具体网络数据包后
       1、单击左侧网络数据包地址,进入数据包详情,查看右侧
       2、右侧:
           1、Headers: 整个请求信息
                General、Response Headers、Request Headers、Query String、Form Data
           2、Preview: 对响应内容进行预览
           3、Response:响应内容

    requests.post()

    1.适用场景

      Post类型请求的网站

    2.参数-data

    response = requests.post(url,data=data,headers=headers)
    # data :post数据(Form表单数据-字典格式)

    3.请求方式特点

    GET请求 : 参数在URL地址中有显示
    POST请求: Form表单提交数据

    有道翻译破解案例(post)

    1.目标

    破解有道翻译接口,抓取翻译结果
    # 结果展示
    请输入要翻译的词语: elephant
    翻译结果: 大象
    **************************
    请输入要翻译的词语: 喵喵叫
    翻译结果: mews

    2.实现步骤

    1、浏览器F12开启网络抓包,Network-All,页面翻译单词后找Form表单数据
    2、在页面中多翻译几个单词,观察Form表单数据变化(有数据是加密字符串)
    3、刷新有道翻译页面,抓取并分析JS代码(本地JS加密)
    4、找到JS加密算法,用Python按同样方式加密生成加密数据
    5、将Form表单数据处理为字典,通过requests.post()的data参数发送

    具体实现

    1.开启F2抓包,找到Form表但数据如下:

    i: 喵喵叫
    from: AUTO
    to: AUTO
    smartresult: dict
    client: fanyideskweb
    salt: 15614112641250
    sign: 94008208919faa19bd531acde36aac5d
    ts: 1561411264125
    bv: f4d62a2579ebb44874d7ef93ba47e822
    doctype: json
    version: 2.1
    keyfrom: fanyi.web
    action: FY_BY_REALTlME

    2.在页面中多翻译几个单词,观察Form表单数据变化

    salt: 15614112641250
    sign: 94008208919faa19bd531acde36aac5d
    ts: 1561411264125
    bv: f4d62a2579ebb44874d7ef93ba47e822
    # 但是bv的值不变

    3.一般为本地js文件加密,刷新页面,找到js文件并分析JS代码

    # 方法1
    Network - JS选项 - 搜索关键词salt
    # 方法2
    控制台右上角 - Search - 搜索salt - 查看文件 - 格式化输出
    
    # 最终找到相关JS文件 : fanyi.min.js

    4.打开JS文件,分析加密算法,用Python实现

    # ts : 经过分析为13位的时间戳,字符串类型
    js代码实现:  "" + (new Date).getTime()
    python实现:  str(int(time.time()*1000))
    
    # salt : ts + 0-9之间的随机数
    js代码实现:  ts+parseInt(10 * Math.random(), 10);
    python实现:  ts + str(randow.randint(0-9))
    
    # sign(设置断点调试,来查看 e 的值,发现 e 为要翻译的单词)
    js代码实现: n.md5("fanyideskweb" + e + salt + "n%A-rKaT5fb[Gy?;N5@Tj")
    python实现:
    from hashlib import md5
    string = "fanyideskweb" + e + salt + "n%A-rKaT5fb[Gy?;N5@Tj"
    s = md5()
    s.update(string.encode())
    sign = s.hexdigest()
    #bv 不变的值,不需要处理,直接复制

    5.代码实现

    import requests
    import time
    import random
    from hashlib import md5
    
    
    class YdSpider():
      def __init__(self):
        # url一定为为F12抓到的headers->General->Request
        self.url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
        self.headers = {
          "Cookie": "OUTFOX_SEARCH_USER_ID=970246104@10.169.0.83; OUTFOX_SEARCH_USER_ID_NCOO=570559528.1224236; _ntes_nnid=96bc13a2f5ce64962adfd6a278467214,1551873108952; JSESSIONID=aaae9i7plXPlKaJH_gkYw; td_cookie=18446744072941336803; SESSION_FROM_COOKIE=unknown; ___rl__test__cookies=1565689460872",
          "Referer": "http://fanyi.youdao.com/",
          "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36",
        }
    
      # 获取salt,sign,ts
      def get_salt_sign_ts(self, word):
        # ts
        ts = str(int(time.time() * 1000))
        # salt
        salt = ts + str(random.randint(0, 9))
        # sign
        string = "fanyideskweb" + word + salt + "n%A-rKaT5fb[Gy?;N5@Tj"
        s = md5()
        s.update(string.encode())
        sign = s.hexdigest()
        return salt, sign, ts
    
      # 主函数
      def attack_yd(self, word):
        # 先拿到salt,sign,ts
        salt, sign, ts = self.get_salt_sign_ts(word)
    
        # 定义form表单数据为字典:data={}
        data = {
          'i': word,
          'from': 'AUTO',
          'to': 'AUTO',
          'smartresult': 'dict',
          'client': 'fanyideskweb',
          'salt': salt,
          'sign': sign,
          'ts': ts,
          'bv': 'cf156b581152bd0b259b90070b1120e6',
          'doctype': 'json',
          'version': '2.1',
          'keyfrom': 'fanyi.web',
          'action': 'FY_BY_REALTlME'
        }
        # 直接发请求:request.post(url,data=data,headers=xxxx)
        res = requests.post(
          url=self.url,
          data=data,
          headers=self.headers
        )
    
        # html = res.text
        html = res.json()
        print(html)
        result = html['translateResult'][0][0]['tgt']
        # 获取相应请求
        return result
    
      # 主函数
      def main(self):
        # 输入翻译单词
        word = input('请输入要翻译的单词')
        res = self.attack_yd(word)
        print("翻译结果",res)
    
    
    if __name__ == '__main__':
      s = YdSpider()
      s.main()
    有道翻译代码实现

    民政部网站数据抓取

    1.目标

    1、URL: http://www.mca.gov.cn/ - 民政数据 - 行政区划代码
       即: http://www.mca.gov.cn/article/sj/xzqh/2019/
    2、目标: 抓取最新中华人民共和国县以上行政区划代码

    2.实现步骤

      1.从民政数据网站中提取最新行政区划代码链接

    # 特点
    1、最新的在上面
    2、命名格式: 2019年X月中华人民共和国县以上行政区划代码
    # 代码实现
    import requests
    from lxml import etree
    import re
    
    url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'}
    html = requests.get(url, headers=headers).text
    parse_html = etree.HTML(html)
    article_list = parse_html.xpath('//a[@class="artitlelist"]')
    
    for article in article_list:
        title = article.xpath('./@title')[0]
        # 正则匹配title中包含这个字符串的链接
        if title.endswith('代码'):
            # 获取到第1个就停止即可,第1个永远是最新的链接
            two_link = 'http://www.mca.gov.cn' + article.xpath('./@href')[0]
            print(two_link)
            break

      2.从二级页面链接中提取真实链接(反爬-相应内容嵌入JS,指向新的链接)

    1、向二级页面链接发请求得到响应内容,并查看嵌入的JS代码
    2、正则提取真实的二级页面链接
    # 相关思路代码
    two_html = requests.get(two_link, headers=headers).text
    # 从二级页面的响应中提取真实的链接(此处为JS动态加载跳转的地址)
    new_two_link = re.findall(r'window.location.href="(.*?)"', two_html, re.S)[0]

      3.在数据库中查询此条链接是否已经爬取,建立增量爬虫

    1、数据库中建立version表,存储爬取的链接
    2、每次执行程序和version表中记录核对,查看是否已经爬取过
    # 思路代码
    cursor.execute('select * from version')
    result = self.cursor.fetchall()
    if result:
        if result[-1][0] == two_link:
            print('已是最新')
        else:
            # 有更新,开始抓取
            # 将链接再重新插入version表记录

      4.代码实现

    '''民政部网站数据抓取(增量爬虫)'''
    import requests
    from lxml import etree
    import re
    import pymysql
    
    class Govement(object):
        def __init__(self):
            self.one_url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
            self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'}
            self.db = pymysql.connect('192.168.153.138','tiger','123456','govdb')
            self.cursor = self.db.cursor()
    
        # 获取假链接
        def get_flase_link(self):
            html = requests.get(self.one_url,headers=self.headers).text
            # 此处隐藏了真实的二级页面的url链接,通过js脚本生成,保存本地文件查看
            parse_html = etree.HTML(html)
            a_list = parse_html.xpath('//a[@class="artitlelist"]')
            for a in a_list:
                title = a.get('title')
                # 正则匹配title中包含这个字符串的链接
                if title.endswith('代码'):
                    # 获取到第1个就停止即可,第1个永远是最新的链接
                    false_link = 'http://www.mca.gov.cn' + a.get('href')
                    break
    
            # 提取真链接
            self.get_real_link(false_link)
    
        def get_real_link(self,false_link):
            # 从已提取的two_link中提取二级页面的真实链接
            two_html = requests.get(false_link, headers=self.headers).text
            # 从二级页面的响应中提取真实的链接(此处为JS动态加载跳转的地址)
            real_two_link = re.findall(r'window.location.href="(.*?)"', two_html, re.S)[0]
    
            self.incre_spider(real_two_link)
    
        def incre_spider(self,real_two_link):
            # 实现增量爬取
            self.cursor.execute('select * from version')
            result = self.cursor.fetchall()
            if result:
                if result[0][0] == real_two_link:
                    print('已是最新,无须爬取')
                else:
                    self.get_data(real_two_link)
                    self.cursor.execute('delete from version')
                    self.cursor.execute('insert into version values(%s)',[real_two_link])
                    self.db.commit()
    
        # 用xpath直接提取数据
        def get_data(self,real_two_link):
            real_two_html = requests.get(real_two_link,headers=self.headers).text
            parse_html = etree.HTML(real_two_html)
            # 基准xpath,提取每个信息的节点列表对象
            tr_list = parse_html.xpath('//tr[@height=19]')
            city_info = {}
            for tr in tr_list:
                city_info['code'] = tr.xpath('./td[2]/text()')[0]
                city_info['name'] = tr.xpath('./td[3]/text()')[0]
                print(city_info)
    
    
    
    if __name__ == '__main__':
        spider = Govement()
        spider.get_flase_link()
    代码实现1
    import requests
    from lxml import etree
    import re
    import pymysql
    class GovmentSpider():
      def __init__(self):
        self.url = 'http://www.mca.gov.cn/article/sj/xzqh/2019/'
        self.headers={'User-Agent':'Mozilla/5.0'}
        self.db = pymysql.connect(
          '127.0.0.1','root','123456','govdb',charset='utf8'
        )
        self.cursor = self.db.cursor()
      #获取假链接
      def get_false_link(self):
        html = requests.get(
          url=self.url,
          headers = self.headers,
        ).text  #等于content.decode()
        #解析
        parse_html = etree.HTML(html)
        print(parse_html)  #网页对象
        a_list = parse_html.xpath('//a[@class="artitlelist"]')
        for a in a_list:
          #titel = a.xpath('./@titel')[0]
          #get()方法:获取某个属性的值
          title = a.get('title')
          if title.endswith('代码'):#末尾以代码结束的
            false_link = 'http://www.mca.gov.cn'+a.get('href')
            break
        # if false_link 在数据库表中没有:
        #   self.get_true_link(false_link)
        #   把链接插入到数据库中
        # else:
        #   print('数据已经是最新,无需爬取')
        self.incr_spider(false_link)
      #增量爬取函数
      def incr_spider(self, false_link):
        sel = 'select url from version '
        self.cursor.execute(sel)
        # fetchall:(('http://xxx.html',),)
        result = self.cursor.fetchall()
        # not result:代表数据库version表中无数据
        if not result:
          self.get_true_link(false_link)
          #可选操作:数据库version表中只保留最新一条数据
          del_ = 'delete from version'
          self.cursor.execute(del_)
          # 把爬取后的url插入到version
          ins = 'insert into version values(%s)'
          self.cursor.execute(ins, [false_link])
          self.db.commit()
        else:
          print('数据已经是最新,无需爬取')
    
      #获取真链接
      def get_true_link(self,false_link):
        #先获取加链接的响应,然后根据响应获取真链接
        html = requests.get(
          url=false_link,
          headers=self.headers
        ).text
        #利用正则提取真是链接
        re_bds = r'window.location.href="(.*?)"'
        pattern = re.compile(re_bds,re.S)
        # 打印看看是否成功爬取头
        # print(html)
        # with open('false_link.html','a') as f:
        #   f.write(html)
        true_link = pattern.findall(html)[0]
        self.save_data(true_link)
        # print(true_link)
    
    
      #提取数据
      def save_data(self,true_link):
        html = requests.get(
          url = true_link,
          headers = self.headers
        ).text
        #xpath提取数据
        parse_html = etree.HTML(html)
        tr_list = parse_html.xpath('.//tr[@height="19"]')
        for tr in tr_list:
          code = tr.xpath('./td[2]/text()')[0].strip()
          name=tr.xpath('./td[3]/text()')[0].strip()
          print(name,code)
    
    
      def main(self):
        self.get_false_link()
    
    if __name__ == '__main__':
        spider=GovmentSpider()
        spider.main()
    代码实现2
  • 相关阅读:
    WinForm画网格并填充颜色
    CodeCombat最后一题GridMancer
    TeeChart缩放
    TeeChart的网络资料
    TeeChart设置图表的标题
    TeeChart取消3D
    TeeChart的坐标轴
    TeeChart入门
    win7下配置IIS
    C#中的编译开关
  • 原文地址:https://www.cnblogs.com/maplethefox/p/11348663.html
Copyright © 2011-2022 走看看