【问题标题】:BeautifulSoup - How to extract email from a website?BeautifulSoup - 如何从网站中提取电子邮件?
【发布时间】:2019-09-15 12:31:52
【问题描述】:

我正在尝试从网站中提取一些信息,但我不知道如何抓取电子邮件。

这段代码对我有用:

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

url = "https://www.eurocham-cambodia.org/member/476/2-LEau-Protection"
uClient = uReq(url)
page_html = uClient.read()
uClient.close()
soup = BeautifulSoup(page_html,"lxml")

members = soup.findAll("b")
for member in members:
    member = members[0].text
print(member)

我想提取数字并与 soup.findAll() 链接,但找不到正确获取文本的方法,因此我使用了 SelectorGadget 工具并尝试了这个:

numbers = soup.select("#content li:nth-child(1)")
for number in numbers:
    number = numbers[0].text
print(number)

links = soup.findAll(".icon-globe+ a")
for link in links:
    link = links[0].text
print(link)

打印正确:

2 L'Eau Protection
 (+33) 02 98 19 43 86
http://www.2leau-protection.com/

现在,在提取电子邮件地址时,我被卡住了。我是新手,任何建议将不胜感激,谢谢!

尝试 1

emails = soup.select("#content li:nth-child(2)")
for email in emails:
    email = emails[0].text
print(email)

我什至不知道它只是打印什么

//<![CDATA[
var l=new Array();
l[0]='>';l[1]='a';l[2]='/';l[3]='<';l[4]='|109';l[5]='|111';l[6]='|99';l[7]='|46';l[8]='|110';l[9]='|111';l[10]='|105';l[11]='|116';l[12]='|99';l[13]='|101';l[14]='|116';l[15]='|111';l[16]='|114';l[17]='|112';l[18]='|45';l[19]='|117';l[20]='|97';l[21]='|101';l[22]='|108';l[23]='|50';l[24]='|64';l[25]='|110';l[26]='|111';l[27]='|105';l[28]='|116';l[29]='|97';l[30]='|109';l[31]='|114';l[32]='|111';l[33]='|102';l[34]='|110';l[35]='|105';l[36]='|32';l[37]='>';l[38]='"';l[39]='|109';l[40]='|111';l[41]='|99';l[42]='|46';l[43]='|110';l[44]='|111';l[45]='|105';l[46]='|116';l[47]='|99';l[48]='|101';l[49]='|116';l[50]='|111';l[51]='|114';l[52]='|112';l[53]='|45';l[54]='|117';l[55]='|97';l[56]='|101';l[57]='|108';l[58]='|50';l[59]='|64';l[60]='|110';l[61]='|111';l[62]='|105';l[63]='|116';l[64]='|97';l[65]='|109';l[66]='|114';l[67]='|111';l[68]='|102';l[69]='|110';l[70]='|105';l[71]='|32';l[72]=':';l[73]='o';l[74]='t';l[75]='l';l[76]='i';l[77]='a';l[78]='m';l[79]='"';l[80]='=';l[81]='f';l[82]='e';l[83]='r';l[84]='h';l[85]=' ';l[86]='a';l[87]='<';
for (var i = l.length-1; i >= 0; i=i-1){
if (l[i].substring(0, 1) == '|') document.write("&#"+unescape(l[i].substring(1))+";");
else document.write(unescape(l[i]));}
//]]>

尝试 2

emails = soup.select(".icon-mail~ a") #follow the same logic
for email in emails:
    email = emails[0].text
print(email)

错误

NameError: name 'email' is not defined

尝试 3

emails = soup.select(".icon-mail~ a")
print(emails)

打印空白

[]

尝试 4,5,6

email = soup.find("a",{"href":"mailto:"}) # Print "None"

email = soup.findAll("a",{"href":"mailto:"}) # Print empty "[]"

email = soup.select("a",{"href":"mailto:"}) # Print a lot of informations but not the one that I need.

【问题讨论】:

    标签: python web-scraping beautifulsoup


    【解决方案1】:
    import re
    text =soup.get_text()
    emails = re.findall(r'[a-z0-9]+@\S+.com', str(text))
    print(emails)
    

    这是从网站打印电子邮件的一种更方便的方式

    【讨论】:

      【解决方案2】:

      我看到你已经有了完全可以接受的答案,但是当我看到那个混淆脚本时,我很着迷,只需要“去混淆”它。

      from bs4 import BeautifulSoup
      from requests import get
      import re
      
      page = "https://www.eurocham-cambodia.org/member/476/2-LEau-Protection"
      
      content = get(page).content
      soup = BeautifulSoup(content, "lxml")
      
      exp = re.compile(r"(?:.*?='(.*?)')")
      # Find any element with the mail icon
      for icon in soup.findAll("i", {"class": "icon-mail"}):
          # the 'a' element doesn't exist, there is a script tag instead
          script = icon.next_sibling
          # the script tag builds a long array of single characters- lets gra
          chars = exp.findall(script.text)
          output = []
          # the javascript array is iterated backwards
          for char in reversed(list(chars)):
              # many characters use their ascii representation instead of simple text
              if char.startswith("|"):
                  output.append(chr(int(char[1:])))
              else:
                  output.append(char)
          # putting the array back together gets us an `a` element
          link = BeautifulSoup("".join(output))
          email = link.findAll("a")[0]["href"][8:]
          # the email is the part of the href after `mailto: `
          print(email)
      

      【讨论】:

      • 大声笑,对混淆脚本感到抱歉,老实说我还不明白你的脚本,但它有效!非常感谢,现在我要学习了
      【解决方案3】:

      无法抓取该网站的给定部分的原因是因为它由 JavaScript 生成并且最初不存在。这可以通过以下代码sn-p来检查

          import lxml
          import requests
      
          page = requests.get(https://www.eurocham-cambodia.org/member/476/2-LEau- Protection).text
          tree = html.fromstring(page)
          print(lxml.html.tostring(tree, pretty_print=True).decode())
      
      

      它为您提供了完整的 HTML 文档,但让我们只关注包含用户个人资料的 div

          <div class="col-sm-12 col-md-6">
             <ul class="iconlist">
                <li>
                   <i class="icon-phone"> </i>(+33) 02 98 19 43 86</li>
      
                <li>
                    <i class="icon-mail"> </i><script type="text/javascript">
                      //<![CDATA[
                      var l=new Array();
          l[0]='>';l[1]='a';l[2]='/';l[3]='<';l[4]='|109';l[5]='|111';l[6]='|99';l[7]='|46';l[8]='|110';l[9]='|111';l[10]='|105';l[11]='|116';l[12]='|99';l[13]='|101';l[14]='|116';l[15]='|111';l[16]='|114';l[17]='|112';l[18]='|45';l[19]='|117';l[20]='|97';l[21]='|101';l[22]='|108';l[23]='|50';l[24]='|64';l[25]='|110';l[26]='|111';l[27]='|105';l[28]='|116';l[29]='|97';l[30]='|109';l[31]='|114';l[32]='|111';l[33]='|102';l[34]='|110';l[35]='|105';l[36]='|32';l[37]='>';l[38]='"';l[39]='|109';l[40]='|111';l[41]='|99';l[42]='|46';l[43]='|110';l[44]='|111';l[45]='|105';l[46]='|116';l[47]='|99';l[48]='|101';l[49]='|116';l[50]='|111';l[51]='|114';l[52]='|112';l[53]='|45';l[54]='|117';l[55]='|97';l[56]='|101';l[57]='|108';l[58]='|50';l[59]='|64';l[60]='|110';l[61]='|111';l[62]='|105';l[63]='|116';l[64]='|97';l[65]='|109';l[66]='|114';l[67]='|111';l[68]='|102';l[69]='|110';l[70]='|105';l[71]='|32';l[72]=':';l[73]='o';l[74]='t';l[75]='l';l[76]='i';l[77]='a';l[78]='m';l[79]='"';l[80]='=';l[81]='f';l[82]='e';l[83]='r';l[84]='h';l[85]=' ';l[86]='a';l[87]='<';
          for (var i = l.length-1; i >= 0; i=i-1){
          if (l[i].substring(0, 1) == '|') document.write("&#"+unescape(l[i].substring(1))+";");
          else document.write(unescape(l[i]));}
          //]]>
                    </script>
                 </li>
                 <li>
                  <i class="icon-globe"></i> <a href="http://www.2leau-protection.com/" target="_blank"><i style="background-color:#2C3E50"></i>http://www.2leau-protection.com/</a>
                </li>
              </ul>
           </div>
      

      仔细看,这是您在 Attempt 中尝试抓取 电子邮件 时在上面抓取的相同脚本 1.

      【讨论】:

        【解决方案4】:

        urllib 和beautifulsoup 组合在某些情况下可能不够用,例如通过API 调用或JavaScript 运行和显示信息的网页。在从外部加载任何内容之前,您将获得该网站的第一个实例。这就是您可能需要以某种方式模拟真实浏览器的原因。您可以使用 javascript 调用来实现,但是有一种更方便的方法。

        Selenium 库被用于自动化网络任务和测试自动化。它也可以用作刮刀。由于它使用浏览器的真正主干(如 Mozilla Gecko 或 Google Chrome 驱动程序),因此在大多数情况下它似乎更强大。以下是如何完成任务的示例:

        from selenium import webdriver
        
        url = "https://www.eurocham-cambodia.org/member/476/2-LEau-Protection"
        
        
        option = webdriver.ChromeOptions()
        option.add_argument("--headless")
        browser = webdriver.Chrome(executable_path="./chromedriver", options=option)
        
        browser.get(url)
        
        print(browser.find_element_by_css_selector(".icon-mail~ a").text)
        

        输出是:

        information@2leau-protection.com
        

        编辑:你可以通过pip install selenium获取selenium,你可以从here找到chrome驱动

        【讨论】:

        • 安装了 Selenium 并下载了 Chrome 驱动程序,我尝试了你的代码,它给了我类似的东西。回溯(最近一次调用最后一次):文件“/Users/monicasen/Desktop/python/Eurocham Gamma. py",第 8 行,在 browser = webdriver.Chrome(executable_path="./chromedriver", options=option) 文件 "/Users/monicasen/anaconda3/lib/python3.7/site-packages/selenium/webdriver /chrome/webdriver.py”,第 81 行,在 init desired_capabilities=desired_capabilities) 文件中“/Users/monicasen/anaconda3/lib/python3.7/site-
        • 您使用哪个操作系统?你确定 selenium 能找到你的 webdriver 吗?
        • 我的是 OS X 10.14.4。不,我不确定大声笑,我以前从未使用过 Selenium,需要阅读文档
        • 假设您使用的是 Windows,如果您的系统中安装了 Google Chrome,您可以使用 browser = webdriver.Chrome(options=option)。如果没有,只需下载适用于 Windows 的 chromedriver,将其放在 python 文件所在的路径中,然后使用 browser = webdriver.Chrome(executable_path="chromedriver.exe", options=option)
        • Mac 怎么样?
        【解决方案5】:

        BeautifulSoup 只处理页面的 HTML,它不执行任何 JavaScrip。电子邮件地址是在加载文档时使用 JavaScript 生成的(可能是为了更难抓取该信息)。

        在这种情况下,它由以下方式生成:

        <script type="text/javascript">
            //<![CDATA[
            var l=new Array();
            l[0]='>';l[1]='a';l[2]='/';l[3]='<';l[4]='|109';l[5]='|111';l[6]='|99';l[7]='|46';l[8]='|110';l[9]='|111';l[10]='|105';l[11]='|116';l[12]='|99';l[13]='|101';l[14]='|116';l[15]='|111';l[16]='|114';l[17]='|112';l[18]='|45';l[19]='|117';l[20]='|97';l[21]='|101';l[22]='|108';l[23]='|50';l[24]='|64';l[25]='|110';l[26]='|111';l[27]='|105';l[28]='|116';l[29]='|97';l[30]='|109';l[31]='|114';l[32]='|111';l[33]='|102';l[34]='|110';l[35]='|105';l[36]='|32';l[37]='>';l[38]='"';l[39]='|109';l[40]='|111';l[41]='|99';l[42]='|46';l[43]='|110';l[44]='|111';l[45]='|105';l[46]='|116';l[47]='|99';l[48]='|101';l[49]='|116';l[50]='|111';l[51]='|114';l[52]='|112';l[53]='|45';l[54]='|117';l[55]='|97';l[56]='|101';l[57]='|108';l[58]='|50';l[59]='|64';l[60]='|110';l[61]='|111';l[62]='|105';l[63]='|116';l[64]='|97';l[65]='|109';l[66]='|114';l[67]='|111';l[68]='|102';l[69]='|110';l[70]='|105';l[71]='|32';l[72]=':';l[73]='o';l[74]='t';l[75]='l';l[76]='i';l[77]='a';l[78]='m';l[79]='"';l[80]='=';l[81]='f';l[82]='e';l[83]='r';l[84]='h';l[85]=' ';l[86]='a';l[87]='<';
            for (var i = l.length-1; i >= 0; i=i-1){
            if (l[i].substring(0, 1) == '|') document.write("&#"+unescape(l[i].substring(1))+";");
            else document.write(unescape(l[i]));}
            //]]>
        </script>
        

        【讨论】:

          【解决方案6】:

          如果您想查找电子邮件地址,可以使用正则表达式来完成。导入模块并搜索文本并提取数据并将其放入列表中。

          import re
          ..
          text = soup.get_text()
          list = re.findall(r'[a-z0-9]+@[gmail|yahoo|rediff].com', text)
          for email in list:
              print(email)
          

          让我知道结果。编码愉快!

          【讨论】:

          • 您可以通过输入 | 添加其他电子邮件技术在它们之间的方括号内。
          • 感谢您的回答。我不知道正则表达式。我导入了模块,它给了我“AttributeError:模块're'没有属性'findAll'”
          • 在这种情况下,您已将其中一个脚本命名为 re.py。检查此问题以获取更多信息:stackoverflow.com/q/35949562/11292068
          • 这个答案不能解决问题。另一方面,在抓取网站时不应使用正则表达式,因为它们容易出错。
          • 其实,一个好的正则表达式在大多数时候是最好的解决方案,但在这种情况下不是这样,这不是一个好的解决方案。
          【解决方案7】:

          我发现这种方法更准确...

          text = get(url).content
          emails = re.findall(r'[a-z0-9]+@\S+.com', str(text))
          

          【讨论】:

          • .io .org .edu。网。 .co.uk .mobi - 以及其他一千封有效电子邮件将不会被捕获。 first_name@ 或 first.lastName@ .. 也不会
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-12-22
          • 2022-01-11
          • 1970-01-01
          • 1970-01-01
          • 2019-08-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多