3

次のコードをpython beautifulsoupで解析するにはどうすればよいですか? 各画像に対応する幅と高さのプロパティ (存在する場合) を取得する必要があります。

以下のコードは、「このページに 3 つの画像があることを意味します。最初の画像は 300x300、中央の画像はサイズが指定されておらず、最後の画像は高さ 1000px です」(ここで説明されているように)

<meta property="og:image" content="http://example.com/rock.jpg" />
<meta property="og:image:width" content="300" />
<meta property="og:image:height" content="300" />
<meta property="og:image" content="http://example.com/rock2.jpg" />
<meta property="og:image" content="http://example.com/rock3.jpg" />
<meta property="og:image:height" content="1000" />

これまでのところ、次のコードがありますが、ディメンションの最初のセットのみが返されます。

images = []
img_list = soup.findAll('meta', {"property":'og:image'})
for og_image in img_list:
    if not og_image.get('content'):
        continue

    image = {'url': og_image['content']}

    width = self.soup.find('meta', {"property":'og:image:width'})
    if width:
        image['width'] = width['content']
    height = self.soup.find('meta', {"property":'og:image:height'})
    if width:
        image['height'] = height['content']

    images.append(image)

ありがとう!

4

3 に答える 3

2

Beautifulsoup ツリー構造を使用する高速なものが必要です。似たようなものを探している人がいる場合に備えて、私が適切だと思った解決策は次のとおりです。

from BeautifulSoup import BeautifulSoup, Tag

soup = BeautifulSoup(html)
images = []
image = {}

img_list = soup.findAll('meta', {"property":'og:image'})
for og_image in img_list:
    if not og_image.get('content'):
        continue

    image = {'url': og_image['content']}
    next = og_image.nextSibling.nextSibling # calling once returns end of line char '\n'

    if next and isinstance(next, Tag) and next.get('property', '').startswith('og:image:'):
        dimension = next['content']
        prop = next.get('property').rsplit(':')[-1]
        image[prop] = dimension

        next = next.nextSibling.nextSibling
        if next and isinstance(next, Tag) and next.get('property', '').startswith('og:image:'):
            dimension = next['content']
            prop = next.get('property').rsplit(':')[-1]
            image[prop] = dimension

    images.append(image)
于 2012-10-01T14:11:36.780 に答える
2

これは BeautifulSoup ではありませんが、pyparsing アプローチは非常に簡単にまとめられます。

html = """
<meta property="og:image" content="http://example.com/rock.jpg" /> 
<meta property="og:image:width" content="300" /> 
<meta property="og:image:height" content="300" /> 
<meta property="og:image" content="http://example.com/rock2.jpg" /> 
<meta property="og:image" content="http://example.com/rock3.jpg" /> 
<meta property="og:image:height" content="1000" /> 
"""

from pyparsing import makeHTMLTags, withAttribute, Optional, Group

# use makeHTMLTags to define tag expressions (allows attributes, whitespace, 
# closing '/', etc., and sets up results names for matched attributes so they
# are easy to get at later)
meta,metaEnd = makeHTMLTags("meta")

# define a copy of the opening tag, filtering on the specific attribute to select for
img_meta = meta.copy().setParseAction(withAttribute(('property','og:image')))
wid_meta = meta.copy().setParseAction(withAttribute(('property','og:image:width')))
hgt_meta = meta.copy().setParseAction(withAttribute(('property','og:image:height')))

# now define the overall expression to look for, and assign names for subexpressions
# for width and height
img_ref = img_meta + Optional(Group(wid_meta)("width")) + Optional(Group(hgt_meta)("height"))

# use searchString to scan through the given text looking for matches
for img in img_ref.searchString(html):
    print "IMAGE:", img.content
    if img.height:
        print "H:", img.height.content
    if img.width:
        print "W:", img.width.content
    print

版画:

IMAGE: http://example.com/rock.jpg
H: 300
W: 300

IMAGE: http://example.com/rock2.jpg

IMAGE: http://example.com/rock3.jpg
H: 1000
于 2012-08-15T09:59:15.340 に答える
0

あなたの問題は解析の問題ではなく、リスト処理の問題です。次のようにリストを「グループ化」します。

[u'http://example.com/rock.jpg', u'300', u'300', u'http://example.com/rock2.jpg', u'http://example.com/rock3.jpg', u'1000']

このようなものに:

[[u'http://example.com/rock.jpg', u'300', u'300'], [u'http://example.com/rock2.jpg'], [u'http://example.com/rock3.jpg', u'1000']]

これが私の解決策です:

import BeautifulSoup as BS                                                  


content = '''<meta property="og:image" content="http://example.com/rock.jpg" 
<meta property="og:image:width" content="300" />                            
<meta property="og:image:height" content="300" />                           
<meta property="og:image" content="http://example.com/rock2.jpg" />         
<meta property="og:image" content="http://example.com/rock3.jpg" />         
<meta property="og:image:height" content="1000" />'''                       


soup = BS.BeautifulSoup(content)                                            
data = [m['content'] for m in soup.findAll('meta')]                         

# Grouping                                                                            
images = []                                                                 
current_image = None                                                        
for d in data:                                                              
    if d.startswith('http'):                                                
        if current_image:                                                   
            images.append(current_image)                                    
        current_image = [d]                                                 
    else:                                                                   
        if current_image:                                                   
            current_image.append(d)                                         
        else:                                                               
            raise Exception('error')                                        
images.append(current_image)                                                

print data                                                                  
print images                                                                
于 2012-08-15T10:09:52.077 に答える