繁体   English   中英

在Python中使用re.findall()进行Web爬网

[英]Using re.findall() in Python for Web Crawling

我正在尝试通过编写一个非常简单的Web爬虫来教自己Python。

它的代码在这里:

#!/usr/bin/python

import sys, getopt, time, urllib, re

LINK_INDEX = 1
links = [sys.argv[len(sys.argv) - 1]]
visited = []
politeness = 10
maxpages = 20

def print_usage():
    print "USAGE:\n./crawl [-politeness <seconds>] [-maxpages <pages>] seed_url"

def parse_args():
    #code for parsing arguments (works fine so didnt need to be included here)

def crawl():
    global links, visited
    url = links.pop()    
    visited.append(url)

    print "\ncurrent url: %s" % url

    response = urllib.urlopen(url)
    html = response.read()

    html = html.lower()

    raw_links = re.findall(r'<a href="[\w\.-]+"', html)

    print "found: %d" % len(raw_links)

    for raw_link in raw_links:
        temp = raw_link.split('"')
        if temp[LINK_INDEX] not in visited and temp[LINK_INDEX] not in links:
            links.append(temp[LINK_INDEX])

    print "\nunvisited:"
    for link in links:
        print link

    print "\nvisited:"
    for link in visited:
        print link

parse_args()

while len(visited) < maxpages and len(links) > 0:
    crawl()
    time.sleep(politeness)

print "politeness = %d, maxpages = %d" % (politeness, maxpages)

我在大约10页的相同工作目录中创建了一个小型测试网络,它们以各种方式链接在一起,它似乎工作正常,但是当我将它自己发送到实际的互联网上时,它无法解析来自它得到的文件。

它能够很好地获取html代码,因为我可以打印出来,但似乎re.findall()部分没有做它应该做的事情,因为链接列表永远不会被填充。 我可能写错了我的正则表达式吗? 它可以很好地找到像<a href="test02.html"这样的字符串,然后从中解析链接,但由于某种原因,它不适用于实际的网页。 它可能是http部分也许正在抛弃它?

我之前从未使用过正则表达式,所以我很确定这就是问题所在。 任何人都可以告诉我如何更好地表达我寻找的模式? 谢谢!

您的正则表达式与href属性的所有有效值都不匹配,例如带斜杠的路径,等等。 使用[^"]+ (与结束双引号不同)而不是[\\w\\.-]+会有所帮助,但这并不重要,因为...... 你不应该用正则表达式解析HTML

列夫已经提到了BeautifulSoup ,你也可以看一下lxml 你可以编写的任何手工制作的正则表达式都会更好。

你可能想要这个:

raw_links = re.findall(r'<a href="(.+?)"', html)

使用括号表示您想要返回的内容,否则您将获得包括<a href=...位在内的整个匹配项。 现在你得到一切,直到结束引号,因为使用了非贪婪的+? 运营商。

更有辨别力的过滤器可能是:

raw_links = re.findall(r'<a href="([^">]+?)"', html)

这匹配除引号和终止括号之外的任何内容。

这些简单的RE将与已经注释的URL匹配,在javascript的位内部使用类似URL的文字字符串,因此请小心使用结果!

问题你的正则表达式。 我可以用很多方法编写一个有效的HTML锚点,你的正则表达式不匹配。 例如,可能存在额外的空格或换行符,并且还有其他可能存在的属性,您尚未将其考虑在内。 此外,你不考虑不同的情况。 例如:

<a  href="foo">foo</a>

<A HREF="foo">foo</a>

<a class="bar" href="foo">foo</a>

这些都不会与你的正则表达式相匹配。

你可能想要更像这样的东西:

<a[^>]*href="(.*?)"

这将匹配一个锚标记start,后跟除>之外的任何字符(这样我们仍然在标记内匹配)。 这可能是classid属性。 然后,在捕获组中捕获href属性的值,您可以通过捕获组进行提取

match.group(1)

href值的匹配也是非贪心的。 这意味着它将匹配可能的最小匹配。 这是因为否则如果你在同一行上有其他标签,你将超出你想要的范围。

最后,您需要添加re.I标志以不区分大小写的方式进行匹配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM