优化我的Python Scraper

时间:2015-06-21 00:58:05

标签: python web-scraping beautifulsoup

这是一个冗长的问题,我可能只需要有人指出我正确的方向。我正在建立一个网络刮刀,从ESPN的网站上获取篮球运动员信息。 URL结构非常简单,因为每个播放器卡在URL中都有一个特定的id。为了获取信息,我编写了一个1-6000的循环来从他们的数据库中抓取玩家。我的问题是,是否有更有效的方法来做到这一点?

from bs4 import BeautifulSoup
from urllib2 import urlopen
import requests 
import nltk
import re




age = [] # Empty List to store player ages

BASE = 'http://espn.go.com/nba/player/stats/_/id/' # Base Structure of Player Card URL
def get_age(BASE): #Creates a function
    #z = range(1,6000) # Create Range from 1 to 6000
    for i in range(1, 6000): # This is a for loop
        BASE_U = BASE + str(i) + '/' # Create URL For Player   
        r = requests.get(BASE_U)
        soup = BeautifulSoup(r.text)
        #Prior to this step, I had to print out the soup object and look through the HTML in order to find the tag that contained my desired information 
        # Get Age of Players        
        age_tables = soup.find_all('ul', class_="player-metadata") # Grabs all text in the metadata tag
        p = str(age_tables) # Turns text into a string
    #At this point I had to look at all the text in the p object and determine a way to capture the age info
        if "Age: " not in p: # PLayer ID doesn't exist so go to next to avoid error
        continue
        else:
            start = p.index("Age: ") + len("Age: ") # Gets the location of the players age 
            end = p[start:].index(")") + start  
            player_id.append(i) #Adds player_id to player_id list
            age.append(p[start:end]) # Adds player's age to age list

get_age(BASE)

任何帮助,即使很小,都会非常感激。即使它只是指向我正确的方向,也不一定是直接的解决方案

谢谢, 本

3 个答案:

答案 0 :(得分:1)

它就像网络安全中的端口扫描程序一样,多线程会让你的编程速度更快。

答案 1 :(得分:1)

不仅更高效,而且更有条理和可扩展的方法将涉及切换到Scrapy网络抓取框架。

您遇到的主要性能问题是因为"阻塞"当前方法的性质 - Scrapy可以解决这个问题,因为它基于twisted并且是完全异步的。

答案 2 :(得分:0)

我可能会从http://espn.go.com/nba/players开始,并使用以下正则表达式来获取团队名单网址...

\href="(/nba/teams/roster\?team=[^"]+)">([^<]+)</a>\

然后我会得到结果匹配组,其中\ 1是URL的最后一部分,\ 2是团队名称。然后我会使用这些网址抓取每个团队名单页面,寻找玩家网址......

\href="(http://espn.go.com/nba/player/_/id/[^"]+)">([^<]+)</a>\

我终于得到了结果匹配组,其中\ 1是播放器页面的URL,\ 2是播放器名称。我会抓取每个结果URL以获取我需要的信息。

正则表达式是炸弹。

希望这有帮助。