Python 如何从所有URL提取数据,而不仅仅是第一个URL

Python 如何从所有URL提取数据,而不仅仅是第一个URL,python,csv,for-loop,web-scraping,beautifulsoup,Python,Csv,For Loop,Web Scraping,Beautifulsoup,此脚本正在生成一个csv,其中只包含一个URL中的数据。应该有98组结果,但是for循环没有通过第一个url 今天我已经做了12个多小时了,为了得到正确的结果,我缺少了什么 导入请求 进口稀土 从bs4导入BeautifulSoup 导入csv #Read csv csvfile = open("gyms4.csv") csvfilelist = csvfile.read() def get_page_data(urls): for url in urls: r = r

此脚本正在生成一个csv,其中只包含一个URL中的数据。应该有98组结果,但是
for
循环没有通过第一个url

今天我已经做了12个多小时了,为了得到正确的结果,我缺少了什么

导入请求 进口稀土 从bs4导入BeautifulSoup 导入csv

#Read csv
csvfile = open("gyms4.csv")
csvfilelist = csvfile.read()

def get_page_data(urls):
    for url in urls:
        r = requests.get(url.strip())
        soup = BeautifulSoup(r.text, 'html.parser')
        yield soup    # N.B. use yield instead of return

print r.text

with open("gyms4.csv") as url_file:
    for page in get_page_data(url_file):
        name = page.find("span",{"class":"wlt_shortcode_TITLE"}).text
        address = page.find("span",{"class":"wlt_shortcode_map_location"}).text
        phoneNum = page.find("span",{"class":"wlt_shortcode_phoneNum"}).text
        email = page.find("span",{"class":"wlt_shortcode_EMAIL"}).text

        th = pages.find('b',text="Category")
        td = th.findNext()
        for link in td.findAll('a',href=True):
            match = re.search(r'http://(\w+).(\w+).(\w+)', link.text)
            if match:
                web_address = link.text

gyms = [name,address,phoneNum,email,web_address]
gyms.append(gyms)

#Saving specific listing data to csv
with open ("xgyms.csv", "w") as file:
    writer = csv.writer(file)
    for row in gyms:
        writer.writerow([row])

您的代码中有3个for循环,但没有指定哪一个导致问题。我假设它是
get\u page\u date()
函数中的一个

您在第一次运行时使用
return
assignemt将looop完全保留。这就是为什么您永远无法访问第二个url

至少有两种可能的解决方案:

  • 将url的每一行解析后附加到一个列表并返回该列表
  • 将处理代码移动到循环中,并将解析后的数据附加到循环中的
    gyms

  • 正如Alex.S所说,
    get\u page\u data()
    在第一次迭代时返回,因此以后的URL永远不会被访问。此外,从页面中提取数据的代码需要为下载的每个页面执行,因此它也需要处于循环中。您可以将
    get\u page\u data()
    转换为一个生成器,然后像这样迭代页面:

    def get_page_data(urls):
        for url in urls:
            r = requests.get(url.strip())
            soup = BeautifulSoup(r.text, 'html.parser')
            yield soup    # N.B. use yield instead of return
    
    with open("gyms4.csv") as url_file:
        for page in get_page_data(url_file):
            name = page.find("span",{"class":"wlt_shortcode_TITLE"}).text
            address = page.find("span",{"class":"wlt_shortcode_map_location"}).text
            phoneNum = page.find("span",{"class":"wlt_shortcode_phoneNum"}).text
            email = page.find("span",{"class":"wlt_shortcode_EMAIL"}).text
            # etc. etc.
    
    您可以在下载和处理每个页面时将数据写入CSV文件,也可以将数据累积到一个列表中,然后使用
    CSV.writer.writerows()
    将其写入一个列表中


    您还应该将URL列表传递给
    get\u page\u data()
    ,而不是从全局变量访问它。

    现在就开始处理这个问题。它会说
    “url”
    不是defined@McLeodx:哦,那有点打字错误。您应该向
    get\u page\u data()
    传递URL序列,例如其他iterable的列表,而不是从函数中引用全局变量。我已经更新了答案以更正它。它现在通过了一个开放的文件,这是一个iterable。我必须承认,我现在很困惑。我得到了关于“Nonetype”对象没有“text”属性的错误。而且,我还以为文件必须在BeatifulSoup代码之前打开?!我显然遗漏了一些东西。
    r.text
    的计算结果为
    None
    ,这意味着
    requests.get()
    没有下载页面。你需要看看这是为什么。下载前请尝试打印url,下载后再打印
    r.text
    。当我打印
    csvfilelist
    时,我会得到url列表,但打印
    r.text
    会显示
    NameError:name'r'未定义
    ,打印
    get\u page\u data
    会显示
    TypeError:get\u page\u data()正好需要一个参数(给定0)
    。我要将上面的代码更改为当前使用的代码