質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

1756閲覧

div class="a1"へ要素をまとめる方法について

hiono

総合スコア7

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2016/07/20 00:18

編集2016/07/20 01:17

###前提・実現したいこと
以下のようなhtmlのdataをpythonを使って処理しようとしています。モジュールはlxmlをiportして扱おうとしています

html

1<div class='a'><img src='aa.jpg'></div> 2<div class='b'><img src='ab.jpg'></div> 3<div class='b'><img src='ac.jpg'></div> 4<div class='b'><img src='ad.jpg'></div> 5<div class='a'><img src='ba.jpg'></div> 6<div class='b'><img src='bb.jpg'></div> 7<div class='b'><img src='bc.jpg'></div>

これを

html

1<div class='a'><img src='aa.jpg'> 2<img src='ab.jpg'> 3<img src='ac.jpg'> 4<img src='ad.jpg'></div> 5<div class='a'><img src='ba.jpg'> 6<img src='bb.jpg'> 7<img src='bc.jpg'></div>

のように変換したいと思っています

###やったこと
find('.//div[@class="b"]') でサーチして子要素をclass='a'の配下にappendしようととしたのですが直前のclass='a'の位置をどうすれば取得できるのかがわからず、断念してしまいました。

このような場合はそもそも上のやり方であっているのか、それとも他にスマートなやり方があるのか、lxmlの操作に不慣れなため判断ができません

なにか良い方法があればよろしくお願いします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

shell

1dockerdev@py3:~$ cat a 2#!/usr/bin/env python3 3# -*- coding: utf-8 -*- 4import lxml.html 5 6html = """ 7<div class='a'><img src='aa.jpg'></div> 8<div class='b'><img src='ab.jpg'></div> 9<div class='b'><img src='ac.jpg'></div> 10<div class='b'><img src='ad.jpg'></div> 11<div class='a'><img src='ba.jpg'></div> 12<div class='b'><img src='bb.jpg'></div> 13<div class='b'><img src='bc.jpg'></div> 14<div class='a'><img src='ca.jpg'></div> 15<div class='b'><img src='cb.jpg'></div> 16""" 17doc = lxml.html.fromstring(html) 18# next がclass="b"の間はclass="a"にappend 19for e in doc.findall('.//div[@class="a"]'): 20 n = e.getnext() 21 while True: 22 if n != None and n.get('class') == 'b': 23 for img in n: 24 if img.tag == 'img': 25 e.append(img) 26 else: 27 break 28 n = n.getnext() 29# 不要なdivを一気に消す 30for e in doc.findall('.//div[@class="b"]'): 31 parent = e.getparent() 32 parent.remove(e) 33 34print(lxml.etree.tostring(doc, pretty_print=True).decode('utf8')) 35dockerdev@py3:~$ python3 a 36python3 a 37<div><div class="a"><img src="aa.jpg"/><img src="ab.jpg"/><img src="ac.jpg"/><img src="ad.jpg"/></div> 38<div class="a"><img src="ba.jpg"/><img src="bb.jpg"/><img src="bc.jpg"/></div> 39<div class="a"><img src="ca.jpg"/><img src="cb.jpg"/></div> 40</div> 41 42dockerdev@py3:~$

投稿2016/07/20 03:35

編集2016/07/20 05:03
hiono

総合スコア7

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

argius

2016/07/20 03:50

これだと次のclass="a"が前のclass="a"の中に入ってしまわないですか?
hiono

2016/07/20 05:04

確認ありがとうございます。一応自分の期待通りにはなっていましたので実行結果を追加しました
argius

2016/07/20 06:05

あれ、私の手元でも再確認してみましたが、ちゃんとできてますね。 大変失礼しました。
guest

0

ベストアンサー

前後関係だと、lxmlにかかわらずイテレーションで処理するしか無いような。たぶん。

divを1個ずつ見ていって、
親(class=a)が出てきたら、
→最初の親なら、それを「最初の要素(top)」「今の親(parent)」にセット。
→そうでないなら、「今の親」に自分を追加し、自分が「今の親」になる。
子(class=b)が出てきたら、下の要素だけを「今の親」に追加。

lang

1import lxml.html 2 3html = """ 4<div class='a'><img src='aa.jpg'></div> 5<div class='b'><img src='ab.jpg'></div> 6<div class='b'><img src='ac.jpg'></div> 7<div class='b'><img src='ad.jpg'></div> 8<div class='a'><img src='ba.jpg'></div> 9<div class='b'><img src='bb.jpg'></div> 10<div class='b'><img src='bc.jpg'></div> 11<div class='a'><img src='ca.jpg'></div> 12<div class='b'><img src='cb.jpg'></div> 13""" 14 15top = None 16parent = None 17 18dom = lxml.html.fromstring(html) 19for div in dom.iterfind(".//div"): 20 if div.get("class") == "a": 21 if parent is None: 22 top = div 23 parent = div 24 else: 25 parent.append(div) 26 parent = div 27 else: 28 parent.append(div[0]) 29 30top # 処理結果

投稿2016/07/20 03:09

argius

総合スコア9388

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hiono

2016/07/20 03:38 編集

やはりそうですか。 もうちょっと綺麗な形になるのかなと思ったのですが、 自分もとりあえず「あなたの回答」のようにbの間回す、そしてまとめてbを消すという感じでやってみました ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問