2008-09-10 30 views
10

Tôi muốn lấy giá trị của trường nhập ẩn trong HTML.Biểu thức chính quy của Python để phân tích cú pháp HTML (BeautifulSoup)

<input type="hidden" name="fooId" value="12-3456789-1111111111" /> 

Tôi muốn viết một biểu thức chính quy bằng Python mà sẽ trả về giá trị của fooId, cho rằng tôi biết dòng trong HTML sau định dạng

<input type="hidden" name="fooId" value="**[id is here]**" /> 

Ai đó có thể cung cấp một ví dụ trong Python để phân tích cú pháp HTML cho giá trị?

Trả lời

27

Đối với trường hợp đặc biệt này, BeautifulSoup là khó khăn hơn để viết hơn một regex, nhưng nó là nhiều hơn nữa mạnh mẽ ... Tôi chỉ góp với ví dụ BeautifulSoup, cho rằng bạn đã biết regexp để sử dụng: -)

from BeautifulSoup import BeautifulSoup 

#Or retrieve it from the web, etc. 
html_data = open('/yourwebsite/page.html','r').read() 

#Create the soup object from the HTML data 
soup = BeautifulSoup(html_data) 
fooId = soup.find('input',name='fooId',type='hidden') #Find the proper tag 
value = fooId.attrs[2][1] #The value of the third attribute of the desired tag 
          #or index it directly via fooId['value'] 
+0

Tôi nghĩ rằng từ khóa "mới" là không phù hợp. –

0
/<input type="hidden" name="fooId" value="([\d-]+)" \/>/ 
5

Parsing là một trong những lĩnh vực mà bạn thực sự không muốn cuộn của riêng bạn nếu bạn có thể tránh nó, vì bạn sẽ được đuổi xuống cạnh trường hợp và lỗi trong nhiều năm đi đến

Tôi khuyên bạn nên sử dụng BeautifulSoup. Nó có một danh tiếng rất tốt và trông từ các tài liệu như nó khá dễ sử dụng.

+1

Tôi đồng ý cho một trường hợp chung, nhưng nếu bạn đang thực hiện một kịch bản một lần để phân tích cú pháp một hoặc hai điều rất cụ thể, một regex chỉ có thể làm cho cuộc sống dễ dàng hơn. Rõ ràng là mong manh hơn, nhưng nếu khả năng bảo trì không phải là vấn đề thì đó không phải là mối quan tâm. Điều đó nói rằng, BeautifulSoup thật tuyệt vời. –

+0

Tôi yêu regex, nhưng phải đồng ý với Orion về điều này. Đây là một trong những thời điểm khi trích dẫn nổi tiếng từ Jamie Zawinski đến với tâm trí: "Bây giờ bạn có hai vấn đề" –

8
import re 
reg = re.compile('<input type="hidden" name="([^"]*)" value="<id>" />') 
value = reg.search(inputHTML).group(1) 
print 'Value is', value 
0
/<input\s+type="hidden"\s+name="([A-Za-z0-9_]+)"\s+value="([A-Za-z0-9_\-]*)"\s*/>/ 

>>> import re 
>>> s = '<input type="hidden" name="fooId" value="12-3456789-1111111111" />' 
>>> re.match('<input\s+type="hidden"\s+name="([A-Za-z0-9_]+)"\s+value="([A-Za-z0-9_\-]*)"\s*/>', s).groups() 
('fooId', '12-3456789-1111111111') 
18

tôi đồng ý với Vinko BeautifulSoup là con đường để đi. Tuy nhiên, tôi khuyên bạn nên sử dụng fooId['value'] đến get the attribute thay vì dựa vào giá trị làm thuộc tính thứ ba.

from BeautifulSoup import BeautifulSoup 
#Or retrieve it from the web, etc. 
html_data = open('/yourwebsite/page.html','r').read() 
#Create the soup object from the HTML data 
soup = BeautifulSoup(html_data) 
fooId = soup.find('input',name='fooId',type='hidden') #Find the proper tag 
value = fooId['value'] #The value attribute 
+0

'mới'? Đó không phải là python! – habnabit

1

Pyparsing là bước tạm thời tốt giữa BeautifulSoup và regex. Nó mạnh mẽ hơn chỉ là regex, vì việc phân tích cú pháp thẻ HTML của nó hiểu các biến thể trong trường hợp, khoảng trắng, sự hiện diện/thiếu/thuộc tính của thuộc tính, nhưng đơn giản hơn để thực hiện loại trích xuất thẻ cơ bản này hơn là sử dụng BS.

Ví dụ của bạn đặc biệt đơn giản vì mọi thứ bạn đang tìm đều nằm trong thuộc tính của thẻ "đầu vào" mở. Dưới đây là một ví dụ pyparsing cho thấy nhiều biến thể trên thẻ đầu vào của bạn mà sẽ cung cấp cho phù hợp regexes, và cũng cho thấy cách KHÔNG để phù hợp với một thẻ nếu nó nằm trong một bình luận:

html = """<html><body> 
<input type="hidden" name="fooId" value="**[id is here]**" /> 
<blah> 
<input name="fooId" type="hidden" value="**[id is here too]**" /> 
<input NAME="fooId" type="hidden" value="**[id is HERE too]**" /> 
<INPUT NAME="fooId" type="hidden" value="**[and id is even here TOO]**" /> 
<!-- 
<input type="hidden" name="fooId" value="**[don't report this id]**" /> 
--> 
<foo> 
</body></html>""" 

from pyparsing import makeHTMLTags, withAttribute, htmlComment 

# use makeHTMLTags to create tag expression - makeHTMLTags returns expressions for 
# opening and closing tags, we're only interested in the opening tag 
inputTag = makeHTMLTags("input")[0] 

# only want input tags with special attributes 
inputTag.setParseAction(withAttribute(type="hidden", name="fooId")) 

# don't report tags that are commented out 
inputTag.ignore(htmlComment) 

# use searchString to skip through the input 
foundTags = inputTag.searchString(html) 

# dump out first result to show all returned tags and attributes 
print foundTags[0].dump() 
print 

# print out the value attribute for all matched tags 
for inpTag in foundTags: 
    print inpTag.value 

Prints:

['input', ['type', 'hidden'], ['name', 'fooId'], ['value', '**[id is here]**'], True] 
- empty: True 
- name: fooId 
- startInput: ['input', ['type', 'hidden'], ['name', 'fooId'], ['value', '**[id is here]**'], True] 
    - empty: True 
    - name: fooId 
    - type: hidden 
    - value: **[id is here]** 
- type: hidden 
- value: **[id is here]** 

**[id is here]** 
**[id is here too]** 
**[id is HERE too]** 
**[and id is even here TOO]** 

Bạn có thể thấy rằng không chỉ pyparsing phù hợp với các biến thể không thể đoán trước, nó trả về dữ liệu trong một đối tượng mà làm cho nó dễ dàng để đọc ra các thuộc tính thẻ cá nhân và giá trị của chúng.

Các vấn đề liên quan