4

我正在为我的学校做一个项目,我想在其中比较诈骗邮件。我找到了这个网站:http ://www.419scam.org/emails/ 现在我想做的是将每个骗局保存在单独的文件中,然后我可以分析它们。到目前为止,这是我的代码:

import BeautifulSoup, urllib2

address='http://www.419scam.org/emails/'
html = urllib2.urlopen(address).read()
f = open('test.txt', 'wb')
f.write(html)
f.close()

这以文本格式保存了整个 html 文件,现在我想剥离文件并将 html 链接的内容保存到骗局:

<a href="2011-12/01/index.htm">01</a> 
<a href="2011-12/02/index.htm">02</a> 
<a href="2011-12/03/index.htm">03</a>

等等

如果我明白了,我仍然需要更进一步并打开保存另一个href。知道如何在一个 python 代码中做到这一点吗?

谢谢!

4

5 回答 5

5

您在 BeautifulSoup 中选择了正确的工具。从技术上讲,您可以在一个脚本中完成所有操作,但您可能需要对其进行分段,因为看起来您将处理数以万计的电子邮件,所有这些都是单独的请求 - 这将需要尽管。

这个页面会给你很多帮助,但这里只是一个小代码片段来帮助你入门。这将获取作为电子邮件索引页面的所有 html 标记,提取它们的 href 链接并在 url 的前面附加一点,以便可以直接访问它们。

from bs4 import BeautifulSoup
import re
import urllib2
soup = BeautifulSoup(urllib2.urlopen("http://www.419scam.org/emails/"))
tags = soup.find_all(href=re.compile("20......../index\.htm")
links = []
for t in tags:
    links.append("http://www.419scam.org/emails/" + t['href'])

're' 是 Python 的正则表达式模块。在第五行中,我告诉 BeautifulSoup 在汤中查找其 href 属性与该正则表达式匹配的所有标签。我选择这个正则表达式来只获取电子邮件索引页面,而不是该页面上的所有 href 链接。我注意到索引页面链接的所有 URL 都有这种模式。

拥有所有正确的“a”标签,然后我遍历它们,通过执行 t['href'] 从 href 属性中提取字符串,并将 URL 的其余部分附加到字符串的前面,以获取原始字符串 URL。

通读该文档,您应该了解如何扩展这些技术以获取单个电子邮件。

于 2012-06-04T18:40:23.143 回答
3

您还可以在requestslxml.html中找到价值。Requests 是另一种发出 http 请求的方法,而 lxml 是解析 xml 和 html 内容的替代方法。

有很多方法可以搜索 html 文档,但您可能希望从cssselect开始。

import requests
from lxml.html import fromstring

url = 'http://www.419scam.org/emails/'
doc = fromstring(requests.get(url).content)

atags = doc.cssselect('a')

# using .get('href', '') syntax because not all a tags will have an href
hrefs = (a.attrib.get('href', '') for a in atags)

或者按照评论中的建议使用.iterlinks(). 请注意,如果您只想要“a”标签,您仍然需要过滤。无论哪种方式, .make_links_absolute() 调用都可能会有所帮助。不过,这是你的作业,所以玩弄它。

doc.make_links_absolute(base_url=url)

hrefs = (l[2] for l in doc.iterlinks() if l[0].tag == 'a')

接下来为您...如何循环并打开所有单独的垃圾邮件链接。

于 2012-06-04T18:35:56.707 回答
2

要获取页面上的所有链接,您可以使用 BeautifulSoup。看看这个页面,它可以提供帮助。它实际上告诉了如何做你所需要的。

要保存所有页面,您可以执行与在当前代码中所做的相同的操作,但在循环中迭代您将提取并存储在列表中的所有链接。

于 2012-06-04T18:08:56.457 回答
2

您可以使用HTML 解析器并指定要搜索的对象的类型。

from HTMLParser import HTMLParser
import urllib2

class MyHTMLParser(HTMLParser):
    def handle_starttag(self, tag, attrs):
        if tag == 'a':
            for attr in attrs:
                if attr[0] == 'href':
                    print attr[1]

address='http://www.419scam.org/emails/'
html = urllib2.urlopen(address).read()
f = open('test.txt', 'wb')
f.write(html)
f.close()

parser = MyHTMLParser()
parser.feed(html)
于 2012-06-04T18:45:17.887 回答
2

这是使用lxml+XPath和的解决方案urllib2

#!/usr/bin/env python2 -u
# -*- coding: utf8 -*-

import cookielib, urllib2
from lxml import etree

cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
page = opener.open("http://www.419scam.org/emails/")
page.addheaders = [('User-agent', 'Mozilla/5.0')]
reddit = etree.HTML(page.read())

# XPath expression : we get all links under body/p[2] containing *.htm
for node in reddit.xpath('/html/body/p[2]/a[contains(@href,".htm")]'):
    for i in node.items():
        url  = 'http://www.419scam.org/emails/' + i[1]
        page = opener.open(url)
        page.addheaders = [('User-agent', 'Mozilla/5.0')]

        lst = url.split('/')
        try:
            if lst[6]: # else it's a "month" link
                filename = '/tmp/' + url.split('/')[4] + '-' + url.split('/')[5]
                f = open(filename, 'w')
                f.write(page.read())
                f.close()
        except:
            pass

# vim:ts=4:sw=4
于 2012-06-04T18:48:10.887 回答