使用 python 和 Beautifulsoup4 从抓取数据中写入和保存 CSV 文件

Posted

技术标签:

【中文标题】使用 python 和 Beautifulsoup4 从抓取数据中写入和保存 CSV 文件【英文标题】:writing and saving CSV file from scraping data using python and Beautifulsoup4 【发布时间】:2015-09-12 15:40:27 【问题描述】:

我正在尝试从 PGA.com 网站上抓取数据,以获取美国所有高尔夫球场的表格。在我的 CSV 表中,我想包含高尔夫球场的名称、地址、所有权、网站、电话号码。有了这些数据,我想对其进行地理编码并将其放入地图并在我的计算机上保存一个本地副本

我使用 Python 和 Beautiful Soup4 来提取我的数据。我已经达到了从网站中提取数据的目的,但是我很难编写脚本来将数据导出到显示我需要的参数的 CSV 文件中。

下面附上我的脚本。我需要帮助创建将提取的代码传输到 CSV 文件的代码以及如何将其保存到我的桌面。

下面是我的脚本:

import csv
import requests 
from bs4 import BeautifulSoup
url = "http://www.pga.com/golf-courses/search?searchbox=Course+Name&searchbox_zip=ZIP&distance=50&price_range=0&course_type=both&has_events=0"
r = requests.get(url)

soup = BeautifulSoup(r.content)

g_data1=soup.find_all("div","class":"views-field-nothing-1")
g_data2=soup.find_all("div","class":"views-field-nothing")


for item in g_data1:
     try:
          print item.contents[1].find_all("div","class":"views-field-counter")[0].text
     except:
          pass  
     try:
          print item.contents[1].find_all("div","class":"views-field-course-type")[0].text
     except:
          pass

for item in g_data2:
   try:
      print item.contents[1].find_all("div","class":"views-field-title")[0].text
   except:
      pass
   try:
      print item.contents[1].find_all("div","class":"views-field-address")[0].text
   except:
      pass
   try:
      print item.contents[1].find_all("div","class":"views-field-city-state-zip")[0].text
   except:
      pass

这是我当前运行脚本时得到的。我想把这些数据做成一个 CSV 表,以便以后进行地理编码。

1801 Merrimac Trl
Williamsburg, Virginia 23185-5905

12551 Glades Rd
Boca Raton, Florida 33498-6830
Preserve Golf Club 
13601 SW 115th Ave
Dunnellon, Florida 34432-5621
1000 Acres Ranch Resort 
465 Warrensburg Rd
Stony Creek, New York 12878-1613
1757 Golf Club 
45120 Waxpool Rd
Dulles, Virginia 20166-6923
27 Pines Golf Course 
5611 Silverdale Rd
Sturgeon Bay, Wisconsin 54235-8308
3 Creek Ranch Golf Club 
2625 S Park Loop Rd
Jackson, Wyoming 83001-9473
3 Lakes Golf Course 
6700 Saltsburg Rd
Pittsburgh, Pennsylvania 15235-2130
3 Par At Four Points 
8110 Aero Dr
San Diego, California 92123-1715
3 Parks Fairways 
3841 N Florence Blvd
Florence, Arizona 85132
3-30 Golf & Country Club 
101 Country Club Lane
Lowden, Iowa 52255
401 Par Golf 
5715 Fayetteville Rd
Raleigh, North Carolina 27603-4525
93 Golf Ranch 
406 E 200 S
Jerome, Idaho 83338-6731
A 1 Golf Center 
1805 East Highway 30
Rockwall, Texas 75087
A H Blank Municipal Course 
808 County Line Rd
Des Moines, Iowa 50320-6706
A-Bar-A Ranch Golf Course 
Highway 230
Encampment, Wyoming 82325
A-Ga-Ming Golf Resort, Sundance 
627 Ag A Ming Dr
Kewadin, Michigan 49648-9397
A-Ga-Ming Golf Resort, Torch 
627 Ag A Ming Dr
Kewadin, Michigan 49648-9397
A. C. Read Golf Club, Bayou 
Bldg 3495, Nas Pensacola
Pensacola, Florida 32508
A. C. Read Golf Club, Bayview 
Bldg 3495, Nas Pensacola
Pensacola, Florida 32508

【问题讨论】:

g_data1和g_data2有什么区别?我似乎无法找到它们在输出中的变化。 这将是 views-field-nothing-1 和 views-field-nothing 之间的区别 据我所知,views-field-nothing-1 div 包含图片... 没关系,我明白了。 【参考方案1】:

首先,您要将所有项目放在一个列表中,然后再写入文件,以防在报废时出现错误。而不是打印只是附加到一个列表。 然后你可以写入一个csv文件

f= open('filename', 'wb')
csv_writer = csv.writer(f)
for i in main_list:
    csv_writer.writerow(i)
f.close()

【讨论】:

【参考方案2】:

您真正需要做的就是将您的输出放在一个列表中,然后使用 CSV 库将其导出。我不完全清楚您从 views-field-nothing-1 得到什么,但只关注 view-fields-nothing,您可以执行以下操作:

courses_list=[]

for item in g_data2:
   try:
      name=item.contents[1].find_all("div","class":"views-field-title")[0].text
   except:
       name=''
   try:
      address1=item.contents[1].find_all("div","class":"views-field-address")[0].text
   except:
      address1=''
   try:
      address2=item.contents[1].find_all("div","class":"views-field-city-state-zip")[0].text
   except:
      address2=''

   course=[name,address1,address2]
   courses_list.append(course)

这会将课程放在一个列表中,接下来您可以将它们写入 cvs,如下所示:

import csv

with open ('filename.cv','wb') as file:
   writer=csv.writer(file)
   for row in course_list:
      writer.writerow(row)

【讨论】:

感谢您的帮助!所以我使用 views-field-nothing-1 来生成所有权并判断它是私有的还是公共的。我如何将它与给定的脚本结合起来,如果我希望我的代码使用数据来处理其他页面,因为列表大约有 20 页,我该如何从其他页面中抓取日期?最后,如何将 CSV 文件保存到 Mac 上的本地驱动器? NVM 我知道它是如何保存的 是否可以指定一个文件夹?如何为网站的其他部分制作脚本循环以获取其他数据?如何为我的 cvs 文件创建标题!非常感谢你,这很有帮助! 您可能想阅读有关 Python 列表的教程。标题行只是您要推送到主列表的另一个列表。因此,在推送课程的循环之前,您可以这样做: course_list.append([name,address1,address2]) 我无法真正与网站的其他部分交谈 - 我猜您想要做的是创建一个遍历页面的主 for 循环。因此,假设每个页面都是 www.pga.com/golf-courses/x.html,其中 x 是该搜索字符串 - 您必须弄清楚如何更改该搜索字符串以提供您想要的所有不同页面。生成一个大的参数列表,比如 zip_codes=[20002,20770,77803,...] 然后循环遍历它们,对于每个参数,比如:for zip in zip_codes: url=base_url+zip your code 但这些都是大问题!我建议查看一些 Python 教程,以熟悉其中一些涉及列表和其他数据类型(如 dicts)的基本操作。

以上是关于使用 python 和 Beautifulsoup4 从抓取数据中写入和保存 CSV 文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 和 BeautifulSoup(将网页源代码保存到本地文件中)

使用python抓取并分析数据—链家网(requests+BeautifulSoup)(转)

使用 urllib 和 BeautifulSoup 通过 Python 从 Web 检索信息

python 使用BeautifulSoup和Python从网页中提取文本

如何使用 Python 3.5 和 BeautifulSoup 抓取 href [重复]

Python和BeautifulSoup编码问题[重复]