爬取根据关键字在谷歌搜索引擎进行批量检索,获取不同高校/机构研究人员的电子邮箱

  1. 读取Excel文件“filtered_keywords_with_emails.xlsx”,内容示例如下:
姓名单位Keywords
张三上海交通大学张三 上海交通大学
李四家里蹲大学李四 家里蹲大学
李四家里蹲大学李四 家里蹲大学
王五家里蹲大学王五 家里蹲大学
赵六西北工业大学赵六 西北工业大学
  1. 根据“Keywords”一列,在谷歌搜索引擎中进行批量检索
  2. 在检索到的前三个结果中遍历查找,按照常用的电子邮件正则表达式进行匹配。注意! 找到的email不一定是正确的,需要人工进行辨别
  3. 最后将检索整理好的结果保存在“filtered_keywords_with_emails.xlsx”文件中,它比“filtered_keywords_with_emails.xlsx”多出“Found Emails”一列,内容示例如下:
姓名单位KeywordsFound Emails
张三上海交通大学张三 上海交通大学sz@sjtu.edu.cn
李四家里蹲大学李四 家里蹲大学sl@jld.edu.cn
李四家里蹲大学李四 家里蹲大学sl@jld.edu.cn
王五家里蹲大学王五 家里蹲大学ww@jld.edu.cn
赵六西北工业大学赵六 西北工业大学lz@nwpu.edu.cn
  1. 找到的email不一定是正确的,在代码运行完之后需要人工进行辨别删减

代码如下:

import time
import re
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import TimeoutException

def close_other_tabs(driver):
    # 关闭除了第一个标签页以外的其他所有标签页
    while len(driver.window_handles) > 1:
        driver.switch_to.window(driver.window_handles[-1])
        driver.close()
    driver.switch_to.window(driver.window_handles[0])


# 设置浏览器选项
options = Options()
options.page_load_strategy = 'eager'  # 忽略等待CSS和JavaScript加载完成
options.add_argument('--ignore-certificate-errors')  # 忽略证书错误
options.add_argument('--ignore-ssl-errors')  # 忽略 SSL 错误
driver = webdriver.Chrome(options=options)

# 读取Excel文件
# df = pd.read_excel('filtered_keywords-test.xlsx')  # 假设关键词在第一列
df = pd.read_excel('filtered_keywords_with_emails.xlsx')  # 假设关键词在第一列
if 'Found Emails' not in df.columns:
    df['Found Emails'] = None  # 如果不存在该列,则创建一个新列

# # 设置Chrome WebDriver
# driver = webdriver.Chrome()

# 定义用于匹配电子邮件地址的正则表达式
email_patterns = [r'[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+',
                  r'[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+',
                  r'[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}']

# 定义不想要的电子邮件地址集合
unwanted_emails = {'service@x-mol.com', 'xueshu_support@baidu.com'}

# 创建字典用于存储关键词及其对应的电子邮件地址列表
keyword_emails = {}

for index, row in df.iterrows():  # 遍历DataFrame中的每一行
    keyword = row['Keywords']

    if pd.notna(row['Found Emails']):  # 检查'Found Emails'列是否已填充
        print(f"Skipping '{keyword}', emails already found.")
        continue  # 如果该行已经有数据,则跳过

    # 如果关键词已经在字典中,直接使用之前保存的电子邮件地址
    if keyword in keyword_emails:
        emails = keyword_emails[keyword]
    else:
        close_other_tabs(driver)
        print(f"Searching for '{keyword}'...")
        # emails = []
        emails = set()

        # 记录是否找到电子邮件地址的标志
        email_found = False

        # 打开Google
        driver.get("http://www.google.com")
        time.sleep(2)  # 给页面加载留出时间

        # 找到搜索框,输入关键词并搜索
        search_box = driver.find_element(By.NAME, 'q')
        search_box.send_keys(keyword)
        search_box.send_keys(Keys.RETURN)
        time.sleep(2)  # 给搜索结果页面加载留出时间

        # 找到所有搜索结果的标题并点击前三个结果
        results = driver.find_elements(By.CSS_SELECTOR, 'h3')

        # 遍历前三个结果
        for i in range(3):
            if i > 0:  # 如果不是第一个结果,需要重新找到结果链接
                results = driver.find_elements(By.CSS_SELECTOR, 'h3')
            # 在新标签页中打开链接
            link = results[i].find_element(By.XPATH, '..')  # 获取h3的父元素即a标签
            href = link.get_attribute('href')
            driver.execute_script(f"window.open('{href}');")
            
            # 切换到新标签页
            driver.switch_to.window(driver.window_handles[-1])
            time.sleep(2)  # 等待页面加载

            # 处理新页面的数据

            # 获取当前页面的源代码
            try:
                page_source = driver.page_source
                
                for email_pattern in email_patterns:
                    # 使用正则表达式在页面源代码中查找电子邮件地址
                    found_emails = re.findall(email_pattern, page_source)
                    if found_emails:
                        break

                # found_emails = re.findall(email_pattern1, page_source)
                # if not found_emails:
                #     found_emails = re.findall(email_pattern2, page_source)

                if not found_emails:
                    # 将网页中的 (at) 和 (dot) 替换为 @ 和 .
                    page_source = page_source.replace('(at)', '@').replace('(dot)', '.')
                    page_source = page_source.replace('( at )', '@').replace('( dot )', '.')
                    # 使用正则表达式在页面源代码中查找电子邮件地址
                    for email_pattern in email_patterns:
                        # 使用正则表达式在页面源代码中查找电子邮件地址
                        found_emails = re.findall(email_pattern, page_source)
                        if found_emails:
                            break

                found_emails = set(found_emails) - unwanted_emails  # Remove unwanted emails

                # 如果找到电子邮件地址,打印并设置标志为True
                if found_emails:
                    email_found = True
                    # 将找到的电子邮件地址添加到列表中
                    # emails.extend(found_emails)    
                    emails.update(found_emails)    
                    # 将关键词及对应的电子邮件地址列表存储到字典中
                    keyword_emails[keyword] = emails
                    print("Found emails:")
                    for email in emails:
                        print(email)
                    break  # 停止查找,已经找到电子邮件地址

            except TimeoutException:
                print("Timed out waiting for page to load")
                continue  # 或者尝试再次加载页面或其他恢复操作

            finally:
                # 关闭新标签页并返回搜索结果标签页
                driver.close()
                driver.switch_to.window(driver.window_handles[0])
                time.sleep(2)

    # 将检索到的电子邮件地址添加到当前行的新列中
    df.at[index, 'Found Emails'] = '; '.join(emails)
    
    # 如果在前3个搜索结果中没有找到电子邮件地址,则打印未找到的消息
    if not email_found:
        keyword_emails[keyword] = 'None'
        print("No emails found on the first 3 search results.")

    # 等待一些时间,然后继续下一个关键词的搜索
    time.sleep(5)

    # 保存带有新列的DataFrame到Excel文件
    df.to_excel('filtered_keywords_with_emails.xlsx', index=False)

# 最后关闭浏览器
driver.quit()
   

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一匹好人呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值