2016-02-15 27 views
5

Hãy chịu với tôi. Tôi khá mới ở Python - nhưng có rất nhiều niềm vui. Tôi đang cố gắng để mã một trình thu thập dữ liệu web thu thập dữ liệu thông qua kết quả bầu cử từ cuộc trưng cầu dân ý cuối cùng ở Đan Mạch. Tôi đã quản lý để trích xuất tất cả các liên kết có liên quan từ trang chính. Và bây giờ tôi muốn Python theo dõi mỗi 92 liên kết và thu thập 9 mẩu thông tin từ mỗi trang đó. Nhưng tôi rất khó khăn. Hy vọng bạn có thể cho tôi một gợi ý.Trình thu thập thông tin web - các liên kết sau

Đây là mã của tôi:

import requests 
import urllib2 
from bs4 import BeautifulSoup 

# This is the original url http://www.kmdvalg.dk/ 

soup = BeautifulSoup(urllib2.urlopen('http://www.kmdvalg.dk/').read()) 

my_list = [] 
all_links = soup.find_all("a") 

for link in all_links: 
    link2 = link["href"] 
    my_list.append(link2) 

for i in my_list[1:93]: 
    print i 

# The output shows all the links that I would like to follow and gather information from. How do I do that? 
+0

Bạn có thể đề cập thêm về 9 mẩu thông tin bạn muốn lấy bên trong mỗi liên kết không? – titipata

+0

Wow - các bạn thật là đáng sợ !! Tôi sẽ phải dành thời gian cố gắng để hiểu các giải pháp của bạn. Tôi sẽ quay lại ngay sau khi tôi đã đánh bại họ. CẢM ƠN RẤT NHIỀU! – Metods

+0

@titipat: Có. Hãy xem trên trang con này. Tôi muốn lấy "stemmeberettigede/số người có thể bầu", "Optalte stemmer/count votes", "JA-stemmer/Những người bình chọn có", "NEJ-stemmer/những người bình chọn không", "Blanke stemmer/blank phiếu bầu "," Ugyldige stemmer/phiếu bầu không hợp lệ "và tên của đô thị (Assenskredsen trong trường hợp này) – Metods

Trả lời

4

Một cách tiếp cận đơn giản sẽ được lặp thông qua danh sách các url và phân tích chúng mỗi cá nhân:

for url in my_list: 
    soup = BeautifulSoup(urllib2.urlopen(url).read()) 
    # then parse each page individually here 

Ngoài ra, bạn có thể điều tốc độ lên sử dụng đáng kể Futures.

from requests_futures.sessions import FuturesSession 

def my_parse_function(html): 
    """Use this function to parse each page""" 
    soup = BeautifulSoup(html) 
    all_paragraphs = soup.find_all('p') 
    return all_paragraphs 

session = FuturesSession(max_workers=5) 
futures = [session.get(url) for url in my_list] 

page_results = [my_parse_function(future.result()) for future in results] 
+0

Điều này thật tuyệt vời. Tập lệnh của tôi hiện hoạt động nhờ nhận xét của bạn về việc lặp qua danh sách các url của tôi. – Metods

+0

UPS - đã không được thực hiện. Tôi chắc chắn tất cả các đề xuất khác trên trang này đều mát hơn - nhưng tôi chọn sự yên tâm của lời khuyên mà tôi có thể hiểu được. Cảm ơn. Đây là mã cuối cùng của tôi hoạt động - nếu bạn có đề xuất để làm cho nó thông minh hơn xin vui lòng cho tôi biết. Trân trọng từ phương pháp. – Metods

5

Đây là giải pháp của tôi sử dụng lxml. Nó tương tự như BeautifulSoup

import lxml 
from lxml import html 
import requests 

page = requests.get('http://www.kmdvalg.dk/main') 
tree = html.fromstring(page.content) 
my_list = tree.xpath('//div[@class="LetterGroup"]//a/@href') # grab all link 
print 'Length of all links = ', len(my_list) 

my_list là một danh sách bao gồm tất cả các liên kết. Và bây giờ bạn có thể sử dụng cho vòng lặp để loại bỏ thông tin bên trong mỗi trang.

Chúng tôi có thể lặp qua từng liên kết. Bên trong mỗi trang, bạn có thể trích xuất thông tin làm ví dụ. Điều này chỉ dành cho bảng trên cùng.

table_information = [] 
for t in my_list: 
    page_detail = requests.get(t) 
    tree = html.fromstring(page_detail.content) 
    table_key = tree.xpath('//td[@class="statusHeader"]/text()') 
    table_value = tree.xpath('//td[@class="statusText"]/text()') + tree.xpath('//td[@class="statusText"]/a/text()') 
    table_information.append(zip([t]*len(table_key), table_key, table_value)) 

Đối với bảng bên dưới trang,

table_information_below = [] 
for t in my_list: 
    page_detail = requests.get(t) 
    tree = html.fromstring(page_detail.content) 
    l1 = tree.xpath('//tr[@class="tableRowPrimary"]/td[@class="StemmerNu"]/text()') 
    l2 = tree.xpath('//tr[@class="tableRowSecondary"]/td[@class="StemmerNu"]/text()') 
    table_information_below.append([t]+l1+l2) 

Hope trợ giúp này!

2

Đây sẽ là giải pháp của tôi cho vấn đề của bạn

import requests 
from bs4 import BeautifulSoup 


def spider(): 
    url = "http://www.kmdvalg.dk/main" 
    source_code = requests.get(url) 
    plain_text = source_code.text 
    soup = BeautifulSoup(plain_text, 'html.parser') 

    for link in soup.findAll('div', {'class': 'LetterGroup'}): 
     anc = link.find('a') 
     href = anc.get('href') 

     print(anc.getText()) 
     print(href) 
     # spider2(href) call a second function from here that is similar to this one(making url = to herf) 
     spider2(href) 
     print("\n") 


def spider2(linktofollow): 
    url = linktofollow 
    source_code = requests.get(url) 
    plain_text = source_code.text 
    soup = BeautifulSoup(plain_text, 'html.parser') 

    for link in soup.findAll('tr', {'class': 'tableRowPrimary'}): 
     anc = link.find('td') 

     print(anc.getText()) 
    print("\n") 


spider() 

của nó không được thực hiện ... tôi chỉ nhận được một yếu tố đơn giản từ bảng nhưng bạn sẽ có được ý tưởng và làm thế nào nó để làm việc.

+0

thay vì tìm ('td') trong fucntion thứ hai, bạn có thể sử dụng findAll sử dụng tên của lớp td bạn muốn tìm. – CVasquezG

1

Đây là mã cuối cùng của tôi hoạt động trơn tru. Vui lòng cho tôi biết nếu tôi có thể làm điều đó thông minh hơn!

import urllib2 
from bs4 import BeautifulSoup 
import codecs 

f = codecs.open("eu2015valg.txt", "w", encoding="iso-8859-1") 

soup = BeautifulSoup(urllib2.urlopen('http://www.kmdvalg.dk/').read()) 

liste = [] 

alle_links = soup.find_all("a") 

for link in alle_links: 
    link2 = link["href"] 
    liste.append(link2) 

for url in liste[1:93]: 
    soup = BeautifulSoup(urllib2.urlopen(url).read().decode('iso-8859-1')) 
    tds = soup.findAll('td') 
    stemmernu = soup.findAll('td', class_='StemmerNu') 
    print >> f, tds[5].string,";",tds[12].string,";",tds[14].string,";",tds[16].string,";", stemmernu[0].string,";",stemmernu[1].string,";",stemmernu[2].string,";",stemmernu[3].string,";",stemmernu[6].string,";",stemmernu[8].string,";",'\r\n' 

f.close() 
Các vấn đề liên quan