【问题标题】:How to get the emails out in the table from the given link when email is listed as a link?当电子邮件被列为链接时,如何从给定链接中获取表格中的电子邮件?
【发布时间】:2019-02-12 13:17:40
【问题描述】:

我有一个招募表格的网站,我需要刮桌子。在该表中,只有当我们在新选项卡中打开它们时才能看到存在的电子邮件地址,但它们存在于页面的 html 脚本中。我无法抓取电子邮件。

class HTMLTableParser:    
  def parse_url(self,url):
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'lxml')
    return[(table['id'], self.parse_html_table(table))\
          for table in soup.find_all('table')]

  def parse_html_table(self,table):
     n_columns = 0
     n_rows = 0
     column_names = []

     for row in table.find_all('tr'):
         td_tags = row.find_all('td')
         if len(td_tags)>0:
             n_rows+=1
             if n_columns == 0:
                 n_columns = len(td_tags)

         th_tags = row.find_all('th')
         if len(th_tags) > 0 and len(column_names) == 0:
             for th in th_tags:
                 column_names.append(th.get_text())




    if len(column_names) > 0 and len(column_names) != n_columns:
        raise Exception("Column titles do not match the number of columns")

    columns = column_names if len(column_names) > 0 else range(0, n_columns)

    df = pd.DataFrame(columns = columns,
                     index = range(0, n_rows))

    row_marker = 0
    for row in table.find_all('tr'):
        column_marker = 0
        columns = row.find_all('td')
        for column in columns:
            df.iat[row_marker, column_marker] = column.get_text()
            column_marker += 1
        if len(columns) > 0:
            row_marker += 1

    for col in df:
        try:
            df[col] = df[col].astype(float)
        except ValueError:
            pass

    return df

【问题讨论】:

标签: python-3.x web-scraping


【解决方案1】:

编辑:最初我只回答了如何获取电子邮件。调整答案以获取包含所有其他数据的电子邮件。 编辑 2:与 BS4 4.6 系列兼容。

无法获取该电子邮件,因为它位于锚点的href 中。如果找到,我们将从锚点中提取电子邮件,否则,如果电子邮件不存在,我们将从单元格中提取文本。

由于我并不清楚 100% 代码的最终目标是什么,因此这只是着眼于提取所有单元格,重点是获取原始代码中未捕获的电子邮件。

from bs4 import BeautifulSoup
import requests
import pandas as pd

url = 'https://www.adelaide.edu.au/directory/atoz?dsn=directory.phonebook;orderby=last%2Cfirst%2Cposition_n;m=atoz;page=;perpage=50'

def parse_url(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'lxml')
    return [(table['id'], parse_html_table(table)) for table in soup.find_all('table')]

def parse_html_table(table):
    n_columns = 0
    n_rows = 0
    column_names = []

    column_names = [th.get_text() for th in table.select('th')]
    n_columns = len(column_names)

    rows = table.select('tr')[1:]
    n_rows = len(rows)

    df = pd.DataFrame(columns=column_names, index=range(n_rows))

    r_index = 0
    for row in rows:
        c_index = 0
        for cell in row.select('td'):
            if cell.get('data-th') == 'Email':
                anchor = cell.select_one('a')
                df.iat[r_index, c_index] = anchor.get('href').replace('mailto:', '') if anchor else cell.get_text()
            else:
                df.iat[r_index, c_index] = cell.get_text()
            c_index += 1
        r_index += 1

    return df

print(parse_url(url))

【讨论】:

  • 谢谢,太好了
  • @Albert 如果您认为它回答了您的问题,请不要忘记接受答案。
  • 嘿,当我将它添加到循环中时,我可以单独取出电子邮件,但我无法在我正在导出的数据框中取出它
  • 我很抱歉,我最初只是为了收到电子邮件而回复。您发布的原始代码甚至无法编译,但我会更新答案。
  • 我已经发布了一个更新的答案。我特别专注于提取数据。与此无关的任何内容都被删除了。
猜你喜欢
  • 2016-03-22
  • 1970-01-01
  • 2013-11-25
  • 2011-05-20
  • 1970-01-01
  • 1970-01-01
  • 2021-02-14
  • 2011-12-20
  • 1970-01-01
相关资源
最近更新 更多