网络爬虫 - 以下链接
Posted
技术标签:
【中文标题】网络爬虫 - 以下链接【英文标题】:Web crawler - following links 【发布时间】:2016-05-26 22:51:48 【问题描述】:请多多包涵。我对 Python 很陌生 - 但很有趣。我正在尝试编写一个网络爬虫,该爬虫会爬取丹麦上次公投的选举结果。我已设法从主页中提取所有相关链接。现在我希望 Python 跟踪 92 个链接中的每一个,并从每个页面收集 9 条信息。但我被困住了。希望你能给我一个提示。
这是我的代码:
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?
【问题讨论】:
您能多说一下您想在每个链接中获取的 9 条信息吗? 哇——你们太棒了!我将不得不花一些时间尝试了解您的解决方案。我一了解他们就会回来。非常感谢! @titipat:是的。看看这个子网站。我想抓取“stemmeberettigede / 可以投票的人数”、“Optalte stemmer / 计票”、“JA-stemmer / 投赞成票的人”、“NEJ-stemmer / 投反对票的人”、“Blanke Stemmer / 空白票”、“Ugyldige stemmer / Invalid votes”和市镇名称(在本例中为 Assenskredsen) 啊,我看到@Metods,我会尽快更新我的解决方案。对于lxml
,它基本上会遍历每个 html 标签,您可以在简单的 Web 浏览器上通过 inspect 元素找到这些标签。 /text()
将抓取标签内的文本。
【参考方案1】:
这是我使用lxml
的解决方案。类似于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
是一个包含所有链接的列表。现在您可以使用 for 循环来抓取每个页面内的信息。
我们可以循环遍历每个链接。在每个页面内,您可以提取信息作为示例。这仅适用于顶层表。
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))
对于页面下方的表格,
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)
希望对您有所帮助!
【讨论】:
【参考方案2】:这是我运行流畅的最终代码。请让我知道我是否可以做得更聪明!
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()
【讨论】:
【参考方案3】:这将是我为您解决问题的方法
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()
它还没有完成......我只从表格中得到一个简单的元素,但你知道它应该如何工作。
【讨论】:
而不是 find('td') 在第二个功能中,您可以使用 findAll 使用您要查找的 td 类的名称。【参考方案4】:一种简单的方法是遍历您的 url 列表并单独解析它们:
for url in my_list:
soup = BeautifulSoup(urllib2.urlopen(url).read())
# then parse each page individually here
或者,您可以使用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]
【讨论】:
这真是太棒了。由于您对遍历我的 url 列表的评论,我的脚本现在可以正常工作。 UPS - 没有完成。我相信此页面上的所有其他建议都更酷 - 但我选择我能理解的和平建议。谢谢。这是我的最终代码,如果你有建议让它更聪明,请告诉我。方法的最佳问候。以上是关于网络爬虫 - 以下链接的主要内容,如果未能解决你的问题,请参考以下文章