2012-02-09 22 views
2

我从网站中提取信息并使用Python将其存储到数据库中,其中MySQLdbBeautifulSoup在Python中对多个SQL查询进行线程化的好方法/设计

该网站由约15个不同的城市组织,每个城市有10到150页的任何地方。总共有500页左右。

对于每个城市的每个页面,我使用BeautifulSoup打开网站,提取所有必要的信息,然后执行insert intoupdate SQL查询。

目前我不使用线程,它需要几分钟的时间通过所有500页,因为Python程序...

  1. 打开一个页面。
  2. 提取信息。
  3. 执行SQL查询。
  4. 打开下一页...

理想我会想负载均衡线程具有,比如,打开了每个大约50页10个并发线程。但我认为这可能太复杂,无法编码。

因此,我想每个城市都有一个线程。我怎么做到这一点?

目前我的代码看起来是这样的:

//import threading 
import BeautifulSoup 
import urllib2 
import MySQLdb 

con = MySQLdb.connect(...) 

def open_page(url): 
    cur = con.cursor() 
    // do SQL query 

//Get a dictionary of city URL 

cities = [ 
    'http://example.com/atlanta/', 
    'http://example.com/los-angeles/', 
    ... 
    'http://example.com/new-york/' 
] 

for city_url in cities: 
    soup = BeautifulSoup(urllib2.urlopen(city_url)) 

    // find every page per city 
    pages = soup.findAll('div', { 'class' : 'page' }) 

    for page in pages: 
     page_url = page.find('a')[ 'href' ] 
     open_page(page_url) 
+0

我不确定多线程是否有必要提高脚本的性能。如果是我,我会首先确保autocommit被禁用,正如这篇文章所建议的:http://stackoverflow.com/questions/6482004/pythonmysql-bulk-insert,看看如果单独提高性能。然后我会考虑执行一个或多个语句*每个城市*而不是*每页*。这会严重减少正在执行的语句的数量,只有在耗尽这些选项之后才能看到多线程。 – Hoons 2012-02-10 00:08:06

回答

1

你最初的想法是绝对可行的。只需启动10个等待同一队列上的输入的工作线程。然后你的邮件进程将这些网址放入这个队列中。负载平衡将自动发生。

如果您的SQL绑定是线程安全的,您可以在工作线程中执行INSERT或UPDATE。否则,我会为SQL的东西添加一个线程,等待不同队列上的输入。然后你的工作线程会把查询放入这个队列中,并且SQL线程会执行它。

如果你是谷歌的“python工作线程队列”,你会发现一些例子。

+0

工作线程看起来就像我在找的东西。谢谢! – hobbes3 2012-02-10 02:45:56

相关问题