Невозможно использовать два потока для выполнения двух функций в скрипте - PullRequest
0 голосов
/ 09 сентября 2018

Я создал скребок, использующий python в сочетании с Thread, чтобы ускорить выполнение. Скребок должен анализировать все ссылки, доступные на веб-странице и заканчивающиеся разными алфавитами. Это все их разбирает.

Однако я хочу проанализировать все номера names и phone из этих отдельных ссылок, используя Thread еще раз. Первая часть, которую мне удалось запустить, используя Thread, но я не могу понять, как создать другую Thread для выполнения последней части сценария?

Я мог бы обернуть их в один Thread, но я хочу знать, как использовать два Threads для выполнения двух функций.

Для первой части: я попробовал, как показано ниже, и это сработало

import requests
import threading
from lxml import html

main_url = "https://www.houzz.com/proListings/letter/{}"

def alphabetical_links(mainurl):
    response = requests.get(link).text
    tree = html.fromstring(response)
    return [container.attrib['href'] for container in tree.cssselect(".proSitemapLink a")]

if __name__ == '__main__':
    linklist = []
    for link in [main_url.format(chr(page)) for page in range(97,123)]:
        thread = threading.Thread(target=alphabetical_links, args=(link,))
        thread.start()
        linklist+=[thread]

    for thread in linklist:
        thread.join()

Мой вопрос: как я могу использовать функцию sub_links() в другой Thread

import requests
import threading
from lxml import html

main_url = "https://www.houzz.com/proListings/letter/{}"

def alphabetical_links(mainurl):
    response = requests.get(link).text
    tree = html.fromstring(response)
    return [container.attrib['href'] for container in tree.cssselect(".proSitemapLink a")]

def sub_links(process_links):
    response = requests.get(process_links).text
    root = html.fromstring(response)

    for container in root.cssselect(".proListing"):
        try:
            name = container.cssselect("h2 a")[0].text
        except Exception: name = ""
        try:
            phone = container.cssselect(".proListingPhone")[0].text
        except Exception: phone = ""
        print(name, phone)

if __name__ == '__main__':
    linklist = []
    for link in [main_url.format(chr(page)) for page in range(97,123)]:
        thread = threading.Thread(target=alphabetical_links, args=(link,))
        thread.start()
        linklist+=[thread]

    for thread in linklist:
        thread.join()

Ответы [ 2 ]

0 голосов
/ 09 сентября 2018

Попробуйте обновить alphabetical_links своими собственными потоками:

import requests
import threading
from lxml import html

main_url = "https://www.houzz.com/proListings/letter/{}"


def alphabetical_links(mainurl):
    response = requests.get(mainurl).text
    tree = html.fromstring(response)
    links_on_page = [container.attrib['href'] for container in tree.cssselect(".proSitemapLink a")]
    threads = []
    for link in links_on_page:
        thread = threading.Thread(target=sub_links, args=(link,))
        thread.start()
        threads.append(thread)
    for thread in threads:
        thread.join()


def sub_links(process_links):
    response = requests.get(process_links).text
    root = html.fromstring(response)

    for container in root.cssselect(".proListing"):
        try:
            name = container.cssselect("h2 a")[0].text
        except Exception: name = ""
        try:
            phone = container.cssselect(".proListingPhone")[0].text
        except Exception: phone = ""
        print(name, phone)

if __name__ == '__main__':
    linklist = []
    for link in [main_url.format(chr(page)) for page in range(97,123)]:
        thread = threading.Thread(target=alphabetical_links, args=(link,))
        thread.start()
        linklist+=[thread]


    for thread in linklist:
        thread.join()

Обратите внимание, что это всего лишь пример того, как управлять "внутренними потоками". Из-за многочисленных потоков, которые запускаются одновременно, ваша система может не запустить некоторые из них из-за недостатка ресурсов, и вы получите исключение RuntimeError: can't start new thread. В этом случае вы должны попытаться реализовать ThreadPool

0 голосов
/ 09 сентября 2018

Вы можете запустить больше потоков так же, как вы начали первый

from threading import Thread

t1 = Thread(target=alphabetical_links, kwargs={
    'mainurl':     link,
})
t1.start()

t2 = Thread(target=sub_links, kwargs={
    'process_links':     link,
})
t2.start()
...