【问题标题】:Web Scraper not getting the full data from a websiteWeb Scraper 未从网站获取完整数据
【发布时间】:2019-10-24 14:16:22
【问题描述】:

我正在尝试抓取this 网站以使用python 为献血营准备一个数据库。

首先,在尝试从 requests 或 urllib 获取网站 html 源代码时,有一个 SSl:certificate_verify_error 我通过将 requests.get() 的验证参数设置为 False 或为 urllib 创建未经验证的上下文来绕过它(快速修复),这让我克服了错误,但是当我看到检索到的源 html 代码时,我需要的表格内容是空的,在网站源代码中它们包含在 tbody 标签中,但我的 requests.get() 命令只让我得到这些标签而不是它们之间的内容。我对抓取非常陌生,将不胜感激。太棒了

from urllib.request import urlopen as uReq
import ssl
from bs4 import BeautifulSoup as soup

my_url = 'https://www.eraktkosh.in/BLDAHIMS/bloodbank/campSchedule.cnt'
sp_context = ssl._create_unverified_context()
uClient = uReq(my_url,context=sp_context)
page_html = uClient.read()
uClient.close()
page_soup=soup(page_html,"html.parser")
table = page_soup.find('tbody')
print (table) #this outputs "<tbody></tbody>"
trow = table.find('tr')
print (trow) #this outputs "None"


第一个打印命令给出

<tbody>
</tbody>

第二个输出

None 

【问题讨论】:

    标签: python web-scraping python-requests urllib


    【解决方案1】:

    之所以如此,是因为第一个请求返回一个几乎是空的 html 脚手架。

    您在页面上看到的数据正在由后续的 ajax 请求填充。确切地说是这个https://www.eraktkosh.in/BLDAHIMS/bloodbank/nearbyBB.cnt?hmode=GETNEARBYCAMPS&stateCode=-1&districtCode=-1&_=1560150852947

    您可以通过右键单击 -> 检查 -> 网络选项卡并重新加载页面来检索此信息。

    意见:从该页面提取信息不需要 BeautifulSoup。可以从上述 API 中轻松获取 json 格式的数据。

    希望这会有所帮助。

    【讨论】:

    • 谢谢!我还有一个问题。我猜几乎所有网站都会使用类似于上述方法的方法来检索数据,那么每个网络抓取教程中给出的方法如何没有提及这一点,但他们却设法以 html 格式获取数据?跨度>
    • 只有使用JavaScript在客户端渲染数据的网站才需要这样处理。
    【解决方案2】:

    看看这个 HTTP 调用:

    https://www.eraktkosh.in/BLDAHIMS/bloodbank/nearbyBB.cnt?hmode=GETNEARBYCAMPS&stateCode=-1&districtCode=-1&_=1560150750074

    这是数据的来源。

    你有两个选择:

    1. 执行 HTTP 调用并解析响应
    2. 使用无头浏览器抓取网站。见here

    【讨论】:

      【解决方案3】:

      使用 pandas 和 re

      import requests
      import pandas as pd
      import urllib3; urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
      import re
      
      p1 = re.compile(r"(.*?)<br/>")
      p2 = re.compile(r"href='(.*?)'")
      
      def get_url(html, p): 
          if html == 'NA':
              url = html
          else:
              url = 'https://www.eraktkosh.in' + p.findall(html)[0]
          return url
      
      def get_date(html, p): 
          if html == 'NA':
              date_string = html
          else:
              date_string = p.findall(html)[0]
          return date_string
      
      r = requests.get('https://www.eraktkosh.in/BLDAHIMS/bloodbank/nearbyBB.cnt?hmode=GETNEARBYCAMPS&stateCode=-1&districtCode=-1&_=1560150750074', verify = False).json()
      df = pd.DataFrame(r['data'])
      df[1] = df[1].apply(lambda x: get_date(x, p1))
      df[10] = df[10].apply(lambda x: get_url(x, p2))
      print(df)
      

      【讨论】:

        【解决方案4】:

        使用pandas库将数据保存到csv文件中。

        在浏览器network选项卡中,您将看到campSchedule表数据的JSON data response

        import requests
        import  pandas as pd
        
        url = 'https://www.eraktkosh.in/BLDAHIMS/bloodbank/nearbyBB.cnt?hmode=GETNEARBYCAMPS&stateCode=-1&districtCode=-1&_=1560150855565'
        jsonData = requests.get(url, verify=False).json()
        
        campScheduleData = []
        
        for data in jsonData['data']:
            campSchedule = {"Date":"","Time":"","Camp Name":"","Address":"","State":"","District":"",\
                            "Contact":"","Conducted By":"","Organized by":"","Register":""}
            if "<br/>" in data[1]:
                campSchedule['Date'] = data[1].split("<br/>")[0]
        
            if "href" in data[10]:
                campSchedule['Register'] = "https://www.eraktkosh.in" + data[10].split("href=")[1].split(" ")[0]
        
            campSchedule['Time'] = data[2]
            campSchedule['Camp Name'] = data[3]
            campSchedule['Address'] = data[4]
            campSchedule['State'] = data[5]
            campSchedule['District'] = data[6]
            campSchedule['Contact'] = data[7]
            campSchedule['Conducted By'] = data[8]
            campSchedule['Organized by'] = data[9]
            campScheduleData.append(campSchedule)
        
        df = pd.DataFrame(campScheduleData)
        # it will save csv file in current project directory with campScheduleData.csv file name
        df.to_csv("campSchedule.csv")
        

        如果你没有安装 pandas,安装它:

        pip3 install pandas
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多