【问题标题】:Python - How to print out one line out of a textPython - 如何从文本中打印出一行
【发布时间】:2018-12-18 20:26:24
【问题描述】:

所以我一直在使用 abit 的 bs4 并设法打印出一个文本。现在我设法打印出 var ajaxsearch 哪个 init 来得更多。

我编写了一个代码,它打印出所有包含 javascript 的内容,并打印出 var ajaxsearch 以它开头的位置:

  try:
        product_li_tags = bs4.find_all('script', {'type': 'text/javascript'})
    except Exception:
        product_li_tags = []

    special_code = ''
    for s in product_li_tags:
        if s.text.strip().startswith('var ajaxsearch'):
            special_code = s.text
            break

    print(special_code)

我得到以下输出:

var ajaxsearch = false;
var combinationsFromController ={
  "224114": {
    "attributes_values": {
      "4": "5.5"
    },
    "attributes": [
      22
    ],

    "unit_impact": 0,
    "minimal_quantity": "1",
    "date_formatted": "",
    "available_date": "",
    "id_image": -1,
    "list": "'22'"
  },
  "224140": {
    "attributes_values": {
      "4": "6"
    },
    "attributes": [
      23
    ],
    "unit_impact": 0,
    "minimal_quantity": "1",
    "date_formatted": "",
    "available_date": "",
    "id_image": -1,
    "list": "'23'"
  },
  "224160": {
    "attributes_values": {
      "4": "6.5"
    },
    "attributes": [
      24
    ],
    "unit_impact": 0,
    "minimal_quantity": "1",
    "date_formatted": "",
    "available_date": "",
    "id_image": -1,
    "list": "'24'"
  },
  "224139": {
    "attributes_values": {
      "4": "7"
    },
    "attributes": [
      25
    ],
    "unit_impact": 0,
    "minimal_quantity": "1",
    "date_formatted": "",
    "available_date": "",
    "id_image": -1,
    "list": "'25'"
  },
  "224138": {
    "attributes_values": {
      "4": "7.5"
    },
    "attributes": [
      26
    ],
    "unit_impact": 0,
    "minimal_quantity": "1",
    "date_formatted": "",
    "available_date": "",
    "id_image": -1,
    "list": "'26'"
  },
  "224113": {
    "attributes_values": {
      "4": "8"
    },
    "attributes": [
      27
    ],
    "unit_impact": 0,
    "minimal_quantity": "1",
    "date_formatted": "",
    "available_date": "",
    "id_image": -1,
    "list": "'27'"
  },
  "224129": {
    "attributes_values": {
      "4": "8.5"
    },
    "attributes": [
      28
    ],
    "unit_impact": 0,
    "minimal_quantity": "1",
    "date_formatted": "",
    "available_date": "",
    "id_image": -1,
    "list": "'28'"
  },
  "224161": {
    "attributes_values": {
      "4": "9"
    },
    "attributes": [
      29
    ],
    "unit_impact": 0,
    "minimal_quantity": "1",
    "date_formatted": "",
    "available_date": "",
    "id_image": -1,
    "list": "'29'"
  }
};
var contentOnly = false;
var Blank = 1;
var Format = 2;

意思是当我打印出 s.text 时。我将得到上面代码的输出。小编辑:如果我尝试执行if s.text.strip().startswith('var combinationsFromController'):,它将找不到该值,并且如果我以相反的方式更改它if 'var combinationsFromController' in s.text.strip():,它将打印出与上述相同的输出。

但是我的问题是我只想能够打印出var combinationsFromController 并跳过其余部分,我稍后可以使用 json.loads 将值转换为 json 但在此之前我的问题是,我该如何打印所以我可以设法获得var combinationsFromController 的值?

编辑:可能解决了!

for s in product_li_tags:
            if 'var combinationsFromController' in s.text.strip():
                for line in s.text.splitlines():
                    if line.startswith('var combinationsFromController'):
                        get_full_text = line.strip()
                        get_config = get_full_text.split(" = ")
                        cut_text = get_config[1][:-1]
                        get_json_values = json.loads(cut_text)

【问题讨论】:

标签: python for-loop beautifulsoup


【解决方案1】:

如果我正确理解你的问题,你有一个代表 5 个 javascript 变量的 121 行字符串,并且你想获得一个包含 仅第二个变量的子字符串。

您可以按如下方式使用 Python 字符串操作:

start = special_code.split('\n').index('var combinationsFromController ={')
end   = special_code.split('\n')[start + 1:].index('var contentOnly = false;')
print('\n'.join(lines[start:end + 3]))

使用方法str.index 查找您需要的javascript 变量的出现。 如果顺序变量是任意的,即您不知道目标变量之后的下一个变量的名称是什么,您仍然可以使用类似的字符串操作来获取所需的子字符串。

lines = special_code.split('\n')
start = lines.index('var combinationsFromController ={')
end   = lines[-1]
for i, line in enumerate(lines[start + 1:]):
    if 'var' in line:
        end = start + i
        break
print('\n'.join(lines[start:end + 1]))

【讨论】:

  • 请注意,用这种简单的解决方案解析 javascript 代码(或任何可能包含嵌套语句的语言)充其量是脆弱的 - 通常最好使用不会在技术上等效但文本不同的正确解析器代码(即,如果在第一行的“=”和“{”之间添加一个空格)。
  • 哦,是的,这是真的!因此,与此同时,我尝试做一些不同的事情,并且效果明显!我编辑了我的线程。你怎么看?
  • @brunodesthuilliers 你是完全正确的。正确的 javascript 解析器是最好的选择。
  • 耶!谁知道我能做到这一点,但在你们的帮助下我无法做到!
  • 是的,当然,我的意思是我尝试像你一样做,但我想我有一些错误。所以我试图从你写作并经历那里的那一点找出ish。但我同意。也许我应该这样做。
【解决方案2】:

使用re 和表达式(\{.*?\}); 来捕获var combinationsFromController = 和;var contentOnly = false; 之间的数据

import re

....
print(special_code)
jsonStr = re.search(r'(\{.*?\});', special_code, re.S).group(1)
combinationsFromController = json.loads(jsonStr)

for key in combinationsFromController:
    print(key)
    # 224114
    # 224140
    # 224160

【讨论】:

  • 与 Alessandro Solbiati 的回答相同的警告:这充其量是脆弱的,而适当的 javascript 解析器会更加健壮。
  • 哦,是的,这是真的!因此,与此同时,我尝试做一些不同的事情,并且效果明显!我编辑了我的线程。你怎么看?
猜你喜欢
  • 2018-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-21
  • 2017-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多