编写一个python脚本,递归地遍历页面上的链接

编写一个python脚本,递归地遍历页面上的链接,python,Python,我正在为我的学校做一个项目,我想比较诈骗邮件。我发现这个网站: 现在我想做的是将每一个骗局保存在单独的文件中,然后我可以分析它们。 以下是我目前的代码: import BeautifulSoup, urllib2 address='http://www.419scam.org/emails/' html = urllib2.urlopen(address).read() f = open('test.txt', 'wb') f.write(html) f.close() 这将以文本格式保存整

我正在为我的学校做一个项目,我想比较诈骗邮件。我发现这个网站: 现在我想做的是将每一个骗局保存在单独的文件中,然后我可以分析它们。 以下是我目前的代码:

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>

等等

如果我得到了,我还需要进一步打开save Other href。知道如何在一个python代码中实现吗


谢谢大家!

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


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

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

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

或者按照使用
.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')

下一个是你。。。如何循环并打开所有单独的垃圾邮件链接。

您在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在soup中查找href属性与该正则表达式匹配的所有标记。我选择此正则表达式仅获取电子邮件索引页,而不是该页上的所有href链接。我注意到索引页面链接的所有URL都有这种模式

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

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

您可以使用并指定要搜索的对象的类型

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)

下面是一个使用
lxml
+
XPath
urlib2
的解决方案:

#!/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

现在,我获得了所有链接,并将所有内容保存在
/tmp/
中,如果可以的话,我会投+10票,因为lxml和请求提供了比BeautifulSoup和urllib更具pythonic的API。但是迭代链接可能更容易。有
doc
项目的
make_links\u absolute
iterlinks
方法。@ms4py我忍不住用lxml提供了答案,并出于同样的原因提出了请求。。。使用起来更加方便和愉快。谢谢你的评论。你知道我们是否可以将其递归到多个级别吗?@NeilGhosh你是说从一个页面中删除链接,然后从所有这些链接中删除html吗?是的,基本上我是在尝试查找所有链接,无论它们位于哪个页面,但是在同一个网站上,你必须“访问”一个网页,才能用漂亮的汤把它刮干净。例如,在上面的示例中,您可以
urlopen()
链接
的每个元素,并在每个元素上运行
BeautifulSoup(…)
。如果你在很多页面上这样做的话,这当然会占用大量的资源(网络)。
#!/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