Python 数据多线程解析
我正在寻找一个为多线程Python应用程序优化Python代码的机会 我的代码的工作方式如下:它下载站点地图,将所有链接收集到地图链接中。之后,解析器函数检查找到的每个链接,并收集所需标记的数据Python 数据多线程解析,python,parsing,python-multithreading,python-asyncio,Python,Parsing,Python Multithreading,Python Asyncio,我正在寻找一个为多线程Python应用程序优化Python代码的机会 我的代码的工作方式如下:它下载站点地图,将所有链接收集到地图链接中。之后,解析器函数检查找到的每个链接,并收集所需标记的数据 import threading import requests from bs4 import BeautifulSoup as bs headers = { 'accept':'*/*', 'user-agent':'Mozilla/5.0 (compatible; Googleb
import threading
import requests
from bs4 import BeautifulSoup as bs
headers = {
'accept':'*/*',
'user-agent':'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
}
base_url = 'https://example.com/page.php'
sitemap_url = 'https://example.com/sitemap.xml' #https://exgfmeetworld.xyz/sitemap.xml
# ф-ция парсинга карты сайта
def sitemap(sitemap_url,headers):
map_links =[]
session = requests.Session()
request =session.get(sitemap_url,headers=headers)
if request.status_code == 200:
soup=bs(request.content, 'xml')
for links in soup.find_all('loc'):
map_links.append(links.text)
return map_links
# главная ф-ция парсинга
def parser(base_url,headers):
session = requests.Session()
request =session.get(base_url,headers=headers)
if request.status_code == 200:
soup=bs(request.content, 'html.parser')
#keyword = soup.find_all('h1', attrs={'class':'vedaky'})
keyword = soup.select('h1')[0].get_text()
else:
print ('error')
pass
return keyword
# главная функция парсинга
def main():
all_links=sitemap (sitemap_url,headers)
for i in all_links:
keyword_pars = parser(i,headers)
print (keyword_pars)
if _name_ == '__main__':
main()
我已经尝试过多处理导入池,但它不符合我的目的。我需要非池决策,因为我需要脚本具有更高的性能。我计划在20多个线程中使用它。如果没有适当的链接,我无法测试它,但我认为这将满足您的要求。它通过将列表传递给解析器函数(当然是通过引用传递的),然后将输出“保存”到列表的索引中 注意,我没有添加任何非常需要的错误处理
import threading
import requests
from bs4 import BeautifulSoup as bs
from multiprocessing.dummy import Pool as ThreadPool
SITE_MAP_URL = 'https://exgfmeetworld.xyz/sitemap.xml'
BASE_URL = 'https://example.com/page.php'
HEADERS = {
'accept':'*/*',
'user-agent':'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
}
def get_site_map() -> list:
request = requests.get(SITE_MAP_URL, headers=HEADERS, timeout=5)
links = []
if request.status_code == 200:
soup = bs(request.content, "html.parser")
links = [l.text for l in soup.find_all("loc")]
return links
def parser(link: str):
request = requests.get(link, headers=HEADERS, timeout=5)
if request.status_code == 200:
soup = bs(request.content, "html.parser")
return soup.find("h1").text
return None
# - MAIN
links = get_site_map()
parser_output = []
pool = ThreadPool(20)
results = pool.map(parser, links)
pool.close()
pool.join()
print(results)
那么,您只是想同时刮取多个链接吗?不是简单地调用parseri、headers,而是生成一个新线程?我看到您复制了我的答案并将其粘贴为问题中的代码,可以吗?它起作用了吗?如果是这样的话,那么请接受我的回答,以供未来的观众观看。您确定解析速度较慢,而不是通过网络获取吗?你是怎么测量的?现在需要多长时间?它需要多快?@SwenRhodian这是一个与你的报废相关的错误,而不是我添加的线程。Joshua Nixon谢谢你的回复,你问的链接是。我想我输入了错误的代码,因为我试图在我的机器上启动你的变体。关于代码本身,我有几个问题:1您的脚本只解析BASE_URL,而不使用sitemap.xml上的链接。2从您的代码中,我看到每个URL都会启动一个单独的线程,如何限制线程并使用线程数-20启动我的脚本。它只使用BASE_URL,因为您最初的代码就是这样做的。我会在一秒钟内更新我的答案,应该是你想要的,因为有这么多的链接,它仍然需要一段时间,只有20个线程。我已经尝试过多处理,正如我在我的问题中最初写的那样。对我来说,为每个线程启动一个单独的进程不是一个好的选择。