2009-01-31 55 views
29

Tôi là người mới sử dụng Python. Tôi đang học regex, nhưng tôi cần giúp đỡ ở đây.Cụm từ thông dụng để trích xuất URL từ liên kết HTML

Ở đây có nguồn HTML:

<a href="http://www.ptop.se" target="_blank">http://www.ptop.se</a> 

Tôi đang cố gắng để mã hóa một công cụ mà chỉ in ra http://ptop.se. Bạn co thể giup tôi được không?

+2

trùng lặp: http: // stackoverflow.com/questions/430966/regex-for-links-in-html-text –

+6

Tôi đã rời xa SO một thời gian, thật tuyệt khi thấy tôi đã bỏ lỡ không có gì và mọi người đều KHÔNG hỏi cách phân tích cú pháp HTML với regex mỗi ngày chết tiệt. – bobince

+2

@bobince Nhiều lần một ngày, thật tồi tệ khi tôi tạo ra hai câu hỏi mà tôi có thể chuyển hướng mọi người đến và một câu trả lời biểu mẫu chỉ ra họ ở đó. –

Trả lời

13

Không sử dụng regexes, sử dụng BeautifulSoup. Điều đó, hoặc quá giòn như để sinh ra nó, w3m/lynx và kéo trở lại những gì w3m/lynx render. Đầu tiên là thanh lịch hơn có lẽ, thứ hai chỉ làm việc một heck nhanh hơn rất nhiều trên một số mã unoptimized tôi đã viết một khi trở lại.

11

điều này sẽ hoạt động, mặc dù có thể có nhiều cách thanh lịch hơn.

import re 
url='<a href="http://www.ptop.se" target="_blank">http://www.ptop.se</a>' 
r = re.compile('(?<=href=").*?(?=")') 
r.findall(url) 
+1

(? <= Href = ["']). *? (? = ["']) Chăm sóc duy nhất quoated href cũng – SoulMan

60

Nếu bạn chỉ tìm kiếm một:

import re 
match = re.search(r'href=[\'"]?([^\'" >]+)', s) 
if match: 
    print match.group(0) 

Nếu bạn có một chuỗi dài, và muốn mọi thể hiện của mô hình trong đó:

import re 
urls = re.findall(r'href=[\'"]?([^\'" >]+)', s) 
print ', '.join(urls) 

đâu s là chuỗi mà bạn đang tìm kiếm các kết quả phù hợp.

Giải thích nhanh về thứ e bit regexp:

r'...' là chuỗi "thô". Nó dừng lại bạn phải lo lắng về việc thoát khỏi các ký tự khá nhiều như bình thường. (\ đặc biệt - trong một chuỗi nguyên một \ chỉ là một \ Trong một chuỗi thông thường bạn phải làm \\ mọi thời gian, và điều đó được trong regexps..)

"href=[\'"]?" nói để phù hợp với "href =", có thể theo sau là ' hoặc ". "Có thể" bởi vì thật khó để nói mức độ nghiêm trọng của HTML mà bạn đang xem là gì, và các dấu ngoặc kép không bắt buộc.

Kèm theo bit tiếp theo trong "()" để đặt thành "nhóm", có nghĩa là tách nó ra và trả lại riêng cho chúng tôi. Nó chỉ là một cách để nói "đây là một phần của mô hình mà tôi quan tâm."

"[^\'" >]+" nói để phù hợp với bất kỳ ký tự không', ", >, hoặc một không gian. Về cơ bản đây là danh sách các ký tự kết thúc với URL. Nó cho phép chúng ta tránh việc cố gắng viết một regexp xứng đáng với một URL đầy đủ, điều này có thể phức tạp một chút.

Đề xuất trong câu trả lời khác để sử dụng BeautifulSoup không phải là xấu, nhưng nó đưa ra yêu cầu bên ngoài cao hơn. Thêm vào đó nó không giúp bạn trong mục tiêu của bạn về regexps học tập, mà tôi muốn giả định dự án phân tích cú pháp html cụ thể này chỉ là một phần của.

Nó khá dễ dàng để làm:

from BeautifulSoup import BeautifulSoup 
soup = BeautifulSoup(html_to_parse) 
for tag in soup.findAll('a', href=True): 
    print tag['href'] 

Một khi bạn đã cài đặt BeautifulSoup, anyway.

+4

Một phần của học tập regexes là học tập khi không sử dụng chúng, đây là trường hợp bạn không nên không sử dụng chúng. –

+0

một số trang có định dạng quá tệ đến nỗi thậm chí cả BeautifulSoup cũng không thể tìm thấy các liên kết trong đó. Sau đó, bạn phải nghỉ mát một cái gì đó. –

1

Có, có tấn trong số họ trên regexlib. Điều đó chỉ chứng minh rằng RE không nên được sử dụng để làm điều đó. Sử dụng SGMLParser hoặc BeautifulSoup hoặc viết một trình phân tích cú pháp - nhưng không sử dụng RE's. Những người mà dường như làm việc là cực kỳ compliated và vẫn không bao gồm tất cả các trường hợp.

4

Các quy định về cơ bản không tốt khi phân tích HTML (xem Can you provide some examples of why it is hard to parse XML and HTML with a regex? vì lý do). Những gì bạn cần là một trình phân tích cú pháp HTML. Xem Can you provide an example of parsing HTML with your favorite parser? để biết các ví dụ sử dụng nhiều trình phân tích cú pháp khác nhau.

Cụ thể là bạn sẽ muốn xem câu trả lời của Python: BeautifulSoup, HTMLParserlxml.

8

John Gruber (người đã viết Markdown, mà được làm bằng biểu thức thông thường và được sử dụng ngay tại đây trên Stack Overflow) có một đi vào sản xuất một biểu hiện thường xuyên công nhận URL trong văn bản:

http://daringfireball.net/2009/11/liberal_regex_for_matching_urls

Nếu bạn chỉ muốn lấy URL (nghĩa là bạn không thực sự phân tích cú pháp HTML), điều này có thể nhẹ hơn một trình phân tích cú pháp HTML.

1

Điều này hoạt động khá tốt với việc sử dụng các kết quả tùy chọn (in sau href=) và chỉ nhận liên kết. Thử nghiệm trên http://pythex.org/

(?:href=['"])([:/.A-z?<_&\s=>0-9;-]+) 

Oputput:

trận đấu 1./wiki/Main_Page

Match 2./wiki/Portal: Nội dung

Match 3./wiki/Portal: Featured_content

Phù hợp với 4/wiki/Cổng thông tin: Current_events

trận đấu 5./wiki/đặc biệt: Random

trận đấu 6. //donate.wikimedia.org/wiki/Special:FundraiserRedirector?utm_source=donate & utm_medium = sidebar & utm_campaign = C13_en.wikipedia.org & uselang = vi

+0

Khi nhập cụm từ thông dụng này vào chương trình python (không phải thông qua trang web bạn đã đề cập), nó sẽ gây ra lỗi do việc sử dụng dấu ngoặc kép văn bản ''' hoặc '" '. Để sửa lỗi này, regex phải là:' regex = '(?: href = [\' "]) ([: /. Az? <_&\s=> 0-9; -] +) '' bằng cách thêm một dấu \ trước '' 'hoặc' ''. –

0

regex này có thể giúp bạn, bạn sẽ nhận được nhóm đầu tiên bằng \ 1 hoặc bất kỳ phương pháp nào bạn có bằng ngôn ngữ của mình.

href="([^"]*) 

dụ:

<a href="http://www.amghezi.com">amgheziName</a> 

kết quả:

http://www.amghezi.com 
Các vấn đề liên quan