2011-11-08 19 views
5


Vì vậy, tôi tương đối mới với python, và để tìm hiểu, tôi đã bắt đầu viết một chương trình trực tuyến để wikipedia, tìm liên kết đầu tiên trong phần tổng quan của một ngẫu nhiên bài viết, theo liên kết đó và tiếp tục cho đến khi nó đi vào vòng lặp hoặc tìm trang triết lý (như chi tiết here) và sau đó lặp lại quy trình này cho một bài viết ngẫu nhiên mới một số lần được chỉ định. Sau đó tôi muốn thu thập các kết quả dưới dạng cấu trúc dữ liệu hữu ích, để tôi có thể truyền dữ liệu đến R bằng cách sử dụng Rpy library để tôi có thể vẽ một số sơ đồ mạng (R là khá tốt khi vẽ những thứ tương tự) với mỗi trong sơ đồ biểu thị các trang được truy cập và các mũi tên mà các đường dẫn được lấy từ bài viết bắt đầu đến trang triết lý.Sơ đồ trò chơi triết học Wikipedia trong python và R

Vì vậy, tôi không gặp vấn đề gì khi bắt python trả lại html có cấu trúc khá từ wiki nhưng có một số vấn đề mà tôi không thể hiểu được. Cho đến bây giờ tôi đã chọn liên kết đầu tiên bằng cách sử dụng cssselector từ thư viện lxml. Nó chọn cho liên kết đầu tiên (trong một thẻ) mà là một hậu duệ trực tiếp của thẻ ap, đó là một hậu duệ trực tiếp của một thẻ div với class = "mw-content-lít" như thế này:

user_agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT)' 
    values = {'name' : 'David Kavanagh', 
     'location' : 'Belfast', 
     'language' : 'Python' } 
    headers = { 'User-Agent' : user_agent } 
    encodes = urllib.urlencode(values) 
    req = urllib2.Request(url, encodes, headers) 
    page = urllib2.urlopen(req) 
    root = parse(page).getroot() 
    return root.cssselect("div.mw-content-ltr>p>a")[0].get('href') 

Mã này nằm trong một hàm mà tôi sử dụng để tìm liên kết đầu tiên trong trang. Nó hoạt động cho hầu hết các phần nhưng vấn đề là nếu liên kết đầu tiên là bên trong một số thẻ khác như trái ngược với một hậu duệ trực tiếp của một thẻ p như chúng ta hãy nói một thẻ b hoặc một cái gì đó sau đó tôi bỏ lỡ nó. Như bạn có thể thấy từ bài viết trên wiki, liên kết in nghiêng hoặc bên trong dấu ngoặc đơn không đủ điều kiện cho trò chơi, có nghĩa là tôi không bao giờ nhận được liên kết in nghiêng (tốt) nhưng thường xuyên nhận được liên kết bên trong dấu ngoặc đơn (xấu) và đôi khi bỏ lỡ liên kết đầu tiên trên một trang như liên kết đầu tiên trên bài viết Chủ tịch, đó là phân, nhưng nó được in đậm, vì vậy tôi không hiểu. Tôi đã cố gắng loại bỏ các quy định hậu duệ trực tiếp nhưng sau đó tôi thường xuyên nhận được các liên kết "ở trên" phần tổng quan, thường nằm trong hộp bên, trong thẻ p, trong một bảng, trong cùng div như phần tổng quan.

Vì vậy, phần đầu của câu hỏi của tôi là:

Làm thế nào tôi có thể sử dụng cssselectors hoặc một số chức năng hoặc thư viện khác để chọn liên kết đầu tiên trong phần tổng quan đó không phải là dấu ngoặc đơn bên hoặc in nghiêng. Tôi nghĩ về việc sử dụng các biểu thức thông thường để xem qua html thô nhưng điều đó có vẻ giống như một giải pháp rất vụng về và tôi nghĩ rằng có thể có thứ gì đó đẹp hơn một chút mà tôi chưa từng nghĩ đến.

Vì vậy, hiện tại tôi đang lưu trữ kết quả trong danh sách danh sách. Vì vậy, tôi có một danh sách được gọi là đường dẫn, trong đó có danh sách có chứa các chuỗi có chứa tiêu đề của bài viết wiki.

Phần thứ hai của câu hỏi là: Làm cách nào tôi có thể duyệt qua danh sách danh sách này để thể hiện nhiều đường dẫn hội tụ? Lưu trữ các kết quả như thế này có phải là một ý tưởng hay không? Vì sơ đồ kết thúc trông giống như một cây lộn ngược, tôi nghĩ đến việc tạo ra một loại cây nào đó, nhưng điều đó có vẻ như rất nhiều công việc cho một cái gì đó mang tính khái niệm, khá đơn giản.

Bất kỳ ý tưởng hoặc đề xuất nào sẽ được đánh giá cao.
Chúc mừng,
Davy

+0

Vui lòng không đăng hai câu hỏi khác nhau trong một! – taleinat

+1

Súp đẹp có thể phân tích cú pháp HTML tốt hơn (IMO). Một đối tượng BS có các thuộc tính (trong ý nghĩa hướng đối tượng) sẽ trả về các thẻ lồng nhau cũng như các thuộc tính (trong ý nghĩa thẻ HTML) của thẻ. Nên là một cinch. Không ** sử dụng cụm từ thông dụng để phân tích cú pháp HTML http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – aitchnyu

Trả lời

4

tôi sẽ chỉ cần trả lời câu hỏi thứ hai:

Đối với một sự khởi đầu, chỉ cần giữ một ánh xạ dict một Wikipedia tiêu đề bài viết tiếp theo. Điều này sẽ làm cho nó dễ dàng và nhanh chóng để kiểm tra tôi đã bạn nhấn một bài báo bạn đã tìm thấy trước đây. Về cơ bản, điều này chỉ lưu trữ các đỉnh của đồ thị được chỉ dẫn, được lập chỉ mục bởi nguồn gốc của chúng.

Nếu bạn đến điểm không có đủ hiệu quả (nó có chi phí bộ nhớ đáng kể, khi bạn có hàng triệu bộ nhớ có thể là vấn đề), bạn có thể tìm thấy cấu trúc dữ liệu đồ thị hiệu quả hơn cho phù hợp bạn cần.

EDIT

Ok, tôi sẽ trả lời câu hỏi đầu tiên cũng ...

Đối với phần đầu tiên, tôi khuyên bạn nên sử dụng MediaWiki API thay vì nhận được phiên bản HTML và phân tích nó. API cho phép truy vấn một số loại liên kết nhất định, ví dụ: chỉ các liên kết liên wiki hoặc liên kết liên kết ngôn ngữ. Ngoài ra, có Python client libraries cho API này, nên sử dụng nó từ mã Python đơn giản.

Không phân tích cú pháp HTML của trang web nếu nó cung cấp API toàn diện và được làm tài liệu!

+0

Toàn bộ wikipedia tiếng Anh ít hơn 4 triệu bài viết. Bạn có thể chèn mẫu ngẫu nhiên các chuỗi 50 byte ngẫu nhiên 4M vào băm chỉ để kiểm tra xem trình thông dịch có xử lý dễ dàng hay không. –

1

Đối với phần đầu tiên, nó không thể tìm thấy dấu ngoặc với selectors css, bởi vì như xa như html lo ngại ngoặc là chỉ văn bản.

Nếu tôi là bạn, tôi sẽ sử dụng bộ chọn để tìm tất cả các phần tử đoạn thích hợp hợp lệ cho trò chơi.Sau đó, tôi sẽ xem xét văn bản của phần tử đoạn văn và loại bỏ bất kỳ phần tử nào không hợp lệ - ví dụ, bất kỳ thứ gì giữa các dấu ngoặc và bất kỳ thứ gì giữa các thẻ in nghiêng. Sau đó tôi sẽ tìm kiếm văn bản đã xử lý này cho các phần tử liên kết mà tôi cần. Điều này hơi đẹp hơn xử lý thủ công toàn bộ tài liệu html.

Tôi không chắc chắn tôi làm theo chính xác những gì bạn đang làm cho phần thứ hai, nhưng để đại diện cho kết quả tìm kiếm này như một cây: Đây là một ý tưởng tồi khi bạn đang tìm kiếm chu kỳ, cây có thể ' t đại diện.

Đối với cấu trúc dữ liệu, tôi sẽ có danh sách 'nút', trong đó nút đại diện cho một trang và có URL và số lần xuất hiện. Sau đó tôi sẽ sử dụng thuật toán brute force để so sánh danh sách các nút - nếu hai danh sách có một nút giống nhau, bạn có thể hợp nhất chúng, tăng số lần xuất hiện cho mỗi nút được nhân đôi.

Tôi sẽ không sử dụng tiêu chuẩn 'python' danh sách vì điều này không thể lặp lại chính nó. Có thể tạo triển khai danh sách liên kết của riêng bạn để chứa các nút.

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