在Python中线程化多个SQL查询的好实践/设计是什么

2 投票
2 回答
1423 浏览
提问于 2025-04-17 12:42

我正在从一个网站提取信息,并使用Python把这些信息存储到数据库里,使用的工具是MySQLdbBeautifulSoup

这个网站按照大约15个不同的城市来组织,每个城市有10到150个页面,总共大约有500个页面。

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

目前我没有使用线程,所以处理这500个页面需要几分钟,因为我的Python程序的步骤是:

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

理想情况下,我希望能通过使用大约10个同时运行的线程,每个线程打开大约50个页面来提高效率。但我觉得这样编写代码可能会太复杂。

所以我在考虑为每个城市使用一个线程。我该怎么做呢?

目前我的代码大概是这样的:

//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 )

2 个回答

1
  1. 用多个线程解析网址。
  2. 从解析出来的网址创建一个.CSV文件。
  3. 创建一个临时表。
  4. 通过这个链接从CSV文件插入数据到临时表。
  5. 从临时表中插入数据到主表,确保没有重复的记录。
1

你的初步想法完全可行。你只需要启动10个工作线程,它们都在同一个队列上等待输入。然后,你的邮件处理程序就可以把网址放到这个队列里。负载均衡会自动进行。

如果你的SQL绑定是线程安全的,那么你可以在工作线程中进行插入或更新操作。否则,我建议再加一个线程专门处理SQL的部分,它会在一个不同的队列上等待输入。这样,工作线程就可以把查询放到这个队列里,而SQL线程会执行这些查询。

如果你在网上搜索“python 工作线程 队列”,你会找到一些例子。

撰写回答