Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 无法使用线程以正确的方式执行脚本_Python_Python 3.x_Web Scraping_Lxml_Python Multithreading - Fatal编程技术网

Python 无法使用线程以正确的方式执行脚本

Python 无法使用线程以正确的方式执行脚本,python,python-3.x,web-scraping,lxml,python-multithreading,Python,Python 3.x,Web Scraping,Lxml,Python Multithreading,我尝试使用python与线程相结合来创建一个scraper,以加快执行时间。scraper应该解析所有的商店名称以及它们在多个页面上的电话号码 脚本正在运行,没有任何问题。由于我对使用线程非常陌生,我很难理解我是以正确的方式工作的 这就是我迄今为止所尝试的: import requests from lxml import html import threading from urllib.parse import urljoin link = "https://www.yellowpag

我尝试使用python与线程相结合来创建一个scraper,以加快执行时间。scraper应该解析所有的商店名称以及它们在多个页面上的电话号码

脚本正在运行,没有任何问题。由于我对使用
线程非常陌生,我很难理解我是以正确的方式工作的

这就是我迄今为止所尝试的:

import requests 
from lxml import html
import threading
from urllib.parse import urljoin 

link = "https://www.yellowpages.com/search?search_terms=coffee&geo_location_terms=Los%20Angeles%2C%20CA&page={}"

def get_information(url):
    for pagelink in [url.format(page) for page in range(20)]:
        response = requests.get(pagelink).text
        tree = html.fromstring(response)
        for title in tree.cssselect("div.info"):
            name = title.cssselect("a.business-name span[itemprop=name]")[0].text
            try:
                phone = title.cssselect("div[itemprop=telephone]")[0].text
            except Exception: phone = ""
            print(f'{name} {phone}')

thread = threading.Thread(target=get_information, args=(link,))

thread.start()
thread.join()
问题是无论我是使用
线程运行上述脚本,还是不使用
线程运行上述脚本,我都找不到时间或性能上的任何差异。如果出现错误,如何使用
线程执行上述脚本


编辑:我尝试更改逻辑以使用多个链接。现在可能吗?提前感谢。

您可以使用线程并行刮取多个页面,如下所示:

import requests
from lxml import html
import threading
from urllib.parse import urljoin

link = "https://www.yellowpages.com/search?search_terms=coffee&geo_location_terms=Los%20Angeles%2C%20CA&page={}"

def get_information(url):
    response = requests.get(url).text
    tree = html.fromstring(response)
    for title in tree.cssselect("div.info"):
        name = title.cssselect("a.business-name span[itemprop=name]")[0].text
        try:
            phone = title.cssselect("div[itemprop=telephone]")[0].text
        except Exception: phone = ""
        print(f'{name} {phone}')

threads = []
for url in [link.format(page) for page in range(20)]:
    thread = threading.Thread(target=get_information, args=(url,))
    threads.append(thread)
    thread.start()
for thread in threads:
    thread.join()
请注意,不会保留数据序列。这意味着,如果要逐个刮取页面,则提取的数据序列将是:

page_1_name_1
page_1_name_2
page_1_name_3
page_2_name_1
page_2_name_2
page_2_name_3
page_3_name_1
page_3_name_2
page_3_name_3
而线程数据将混合在一起:

page_1_name_1
page_2_name_1
page_1_name_2
page_2_name_2
page_3_name_1
page_2_name_3
page_1_name_3
page_3_name_2
page_3_name_3

由于全局解释器锁(GIL),线程很少会使代码更快。这是从一个线程开始的单个进程。正在执行的工作没有并发性,因此执行时间大致相同。将单个进程包装到线程中只会使脚本速度变慢。。。您应该并行运行多个进程以减少执行时间如果您需要刮取多个链接,您可以尝试同时刮取它们(几乎同时,正如所提到的,GIL不允许同时实际运行进程),如
thread1=threading.Thread(target=get_information,args=(link1,);thread2=threading.Thread(target=get_信息,args=(link2,);etc
请查看编辑,看看现在是否有任何选项可以提高性能。谢谢大家的宝贵意见。对不起,先生,我的回复太晚了。它工作得非常好。我一直在等待您的在线可用性@sir Andersson。如果你不忙,请看一下这里。谢谢