【问题标题】:Loop not working for scraping data using python and beautifulsoup4循环不适用于使用 python 和 beautifulsoup4 抓取数据
【发布时间】:2015-09-14 02:40:28
【问题描述】:

我的目标是从 PGA 网站上抓取数据,以提取美国的所有高尔夫球场位置。我的目标是从 907 页中刮取姓名、地址、所有权、电话号码和网站。

我已经创建了下面的脚本,但是在创建 CSV 时会产生错误。从脚本创建的 CSV 文件具有前几页和网站页面的数据重复。它没有给出 907 页的全部数据。

如何修复我的脚本,以便它可以抓取所有 907 页并生成包含 PGA 网站上列出的所有高尔夫球场的 CSV?

下面是我的脚本:

import csv
import requests 
from bs4 import BeautifulSoup

for i in range(907):      # Number of pages plus one 
     url = "http://www.pga.com/golf-courses/search?page={}&searchbox=Course+Name&searchbox_zip=ZIP&distance=50&price_range=0&course_type=both&has_events=0".format(i)
     r = requests.get(url)
     soup = BeautifulSoup(r.content)
g_data2=soup.find_all("div",{"class":"views-field-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=''
     try:
          website=item.contents[1].find_all("div",{"class":"views-field-website"})[0].text
     except:
          website=''   
     try:
          Phonenumber=item.contents[1].find_all("div",{"class":"views-field-work-phone"})[0].text
     except:
          Phonenumber=''      

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

     with open ('PGA_Data.csv','a') as file:
          writer=csv.writer(file)
          for row in courses_list:
               writer.writerow(row)

【问题讨论】:

  • 我不明白。您正在获取页面内容 907 次,但只处理最后一次?
  • 我正在尝试从 PGA 网站的 907 个页面或实例中提取数据,并尝试通过创建一个循环来完成该过程,该循环将通过网站并收集所有数据。我需要收集大约 907 页的数据,但我的循环不起作用。
  • 是的,但是每次调用soup = BeautifulSoup(r.content) 都会丢失上一页的所有数据。在获取新网页之前,您需要解析当前网页。
  • 通过解析,我的意思是收集所有信息并将其保存到 csv 文件(脚本的第二部分)
  • 这就是我认为我所做的。我怎样才能不丢失数据?你能帮我构建脚本吗?

标签: python csv beautifulsoup


【解决方案1】:

她是你想要的代码。它会先解析当前页面然后进入下一个页面。 (有一些空白行,希望你能自己解决)。

import csv
import requests 
from bs4 import BeautifulSoup


def encode(l):
    out = []
    for i in l:
        text = str(i).encode('utf-8')
        out.append(''.join([i if ord(i) < 128 else ' ' for i in text])) #taken from Martjin Pieter's answer 
        # http://stackoverflow.com/questions/20078816/replace-non-ascii-characters-with-a-single-space/20078869#20078869
    return out

courses_list = []
for i in range(5):      # Number of pages plus one 
    url = "http://www.pga.com/golf-courses/search?page={}&searchbox=Course+Name&searchbox_zip=ZIP&distance=50&price_range=0&course_type=both&has_events=0".format(i)
    r = requests.get(url)
    soup = BeautifulSoup(r.content)

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

    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=''
        try:
              website= item.contents[1].find_all("div",{"class":"views-field-website"})[0].text
        except:
              website=''   
        try:
              Phonenumber= item.contents[1].find_all("div",{"class":"views-field-work-phone"})[0].text
        except:
              Phonenumber=''      

        course=[name,address1,address2,website,Phonenumber]

        courses_list.append(encode(course))


with open ('PGA_Data.csv','a') as file:
          writer=csv.writer(file)
          for row in courses_list:
               writer.writerow(row)

编辑:在不可避免的 unicode 编码/解码问题之后,我修改了答案,它现在(希望)可以工作。但是http://nedbatchelder.com/text/unipain.html 看到这个。

【讨论】:

  • 我收到此错误。锄头我解决这个问题。 /Final_PGA2.py",第 44 行,在 writer.writerow(row) UnicodeEncodeError: 'ascii' codec can't encode character u'\u201c' in position 35: ordinal not in range(128)
  • @Gonzalo68 是的,这是 csv 写入器的问题,它无法正确处理 Unicode。我正在修改我的答案。看看吧。
猜你喜欢
  • 1970-01-01
  • 2015-09-12
  • 2015-09-16
  • 2020-09-26
  • 2020-06-23
  • 2015-01-09
  • 2019-08-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多