2012-06-04 27 views
4

我正在为我的学校做一个项目,我想在这个项目中比较骗局邮件。我发现这个网站:http://www.419scam.org/emails/ 现在我想要做的是将每个骗局保存在分开的文档中,然后我可以分析它们。 这里是我到目前为止的代码:编写一个通过页面上的链接遍历的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() 

这节省了我的文本格式全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代码中做到这一点?

谢谢!

回答

5

您在BeautifulSoup中选择了正确的工具。从技术上讲,你可以在一个脚本中做到这一点,但你可能想分割它,因为它看起来像你会处理数以万计的电子邮件,所有这些都是单独的请求 - 这将需要一个而。

This page是会帮助你很多,但这里只是一个小小的代码片段,让你开始。这将获得所有电子邮件索引页面的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附加到字符串的前面,以获得原始字符串网址。

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

+0

谢谢@保罗! – 01000001

+0

任何想法,如果我们可以递归到一个以上的水平? – SoulMan

+0

@NeilGhosh你的意思是刮一个页面的链接,然后从所有这些链接刮取html? –

2

要获得页面上的所有链接,您可以使用BeautifulSoup。看看this page,它可以提供帮助。它实际上告诉你如何去做你需要的东西。

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

3

您还可能在requestslxml.html中发现价值。请求是制作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') 

接下来你...如何循环并打开所有的个人垃圾链接的。

+0

我想,如果我可以投票+10,因为LXML和要求提供比BeautifulSoup和urllib的一个更Python的API。 – schlamar

+0

但迭代链接可能会更容易完成。有'doc'对象的'make_links_absolute'和'iterlinks'方法。 – schlamar

+0

@ ms4py我忍不住用lxml提供了一个答案,并且出于同样的原因提出了一个请求......方式更加pythonic和令人愉快的使用。感谢您的评论。 – istruble

2

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

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) 
2

继承人使用lxml + XPathurllib2一个解决方案:

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

现在,我得到所有的链接,我把所有的东西保存在'/ tmp/' –

+0

谢谢,非常感谢! – 01000001

+0

当他们喜欢回复时,这里的人喜欢upvote;) –

相关问题