2012-04-25 30 views
8

Tôi đang cố gắng để xóa dữ liệu bảng thành tệp CSV. Thật không may, tôi đã nhấn một khối đường và đoạn mã sau chỉ lặp lại TD từ TR đầu tiên cho tất cả các TRs tiếp theo.Python beautifulsoup lặp lại trên bảng

import urllib.request 
from bs4 import BeautifulSoup 

f = open('out.txt','w') 

url = "http://www.international.gc.ca/about-a_propos/atip-aiprp/reports-rapports/2012/02-atip_aiprp.aspx" 
page = urllib.request.urlopen(url) 

soup = BeautifulSoup(page) 

soup.unicode 

table1 = soup.find("table", border=1) 
table2 = soup.find('tbody') 
table3 = soup.find_all('tr') 

for td in table3: 
    rn = soup.find_all("td")[0].get_text() 
    sr = soup.find_all("td")[1].get_text() 
    d = soup.find_all("td")[2].get_text() 
    n = soup.find_all("td")[3].get_text() 

    print(rn + "," + sr + "," + d + ",", file=f) 

Đây là tập lệnh Python đầu tiên của tôi nên mọi trợ giúp sẽ được đánh giá cao! Tôi đã xem xét các câu trả lời câu hỏi khác nhưng không thể tìm ra những gì tôi đang làm sai ở đây.

Trả lời

26

Bạn đang bắt đầu ở cấp cao nhất của tài liệu của bạn mỗi khi bạn sử dụng find() hoặc find_all(), vì vậy khi bạn yêu cầu, ví dụ, tất cả các "td" `thẻ bạn đang nhận được tất cả các "td" thẻ trong tài liệu, không chỉ những tài liệu trong bảng và hàng bạn đã tìm kiếm. Bạn cũng có thể không tìm kiếm chúng bởi vì chúng không được sử dụng theo cách viết mã của bạn.

Tôi nghĩ rằng bạn muốn làm một cái gì đó như thế này:

table1 = soup.find("table", border=1) 
table2 = table1.find('tbody') 
table3 = table2.find_all('tr') 

Hoặc, bạn có biết, một cái gì đó nhiều như thế này, với tên biến mô tả nhiều hơn để khởi động:

rows = soup.find("table", border=1).find("tbody").find_all("tr") 

for row in rows: 
    cells = row.find_all("td") 
    rn = cells[0].get_text() 
    # and so on 
6

Vấn đề là mỗi khi bạn đang cố gắng thu hẹp tìm kiếm của bạn (có được td đầu tiên trong tr này, vv) bạn thay vì chỉ gọi lại cho súp. Soup là đối tượng cấp cao nhất - nó đại diện cho toàn bộ tài liệu. Bạn chỉ cần gọi súp một lần, và sau đó sử dụng kết quả của nó thay cho súp cho bước tiếp theo.

Ví dụ (với tên biến thay đổi để được rõ ràng hơn),

table = soup.find('table', border=1) 
rows = table.find_all('tr') 

for row in rows: 
    data = row.find_all("td") 
    rn = data[0].get_text() 
    sr = data[1].get_text() 
    d = data[2].get_text() 
    n = data[3].get_text() 

    print(rn + "," + sr + "," + d + ",", file=f) 

Tôi không chắc rằng tuyên bố in là cách tốt nhất để làm những gì bạn đang cố gắng làm ở đây (tại rất ít nhất, bạn nên sử dụng định dạng chuỗi thay vì bổ sung), nhưng tôi để nguyên nó vì nó không phải là vấn đề cốt lõi.

Ngoài ra, để hoàn thành: soup.unicode sẽ không hoạt động. Bạn không gọi một phương pháp ở đó, và không có nhiệm vụ. Tôi không nhớ BeautifulSoup có một phương pháp có tên unicode ở nơi đầu tiên, nhưng tôi đã quen với BS 3.0 vì vậy nó có thể là mới trong 4.

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