0

我想从这样的成员列表页面收集用户名:http: //www.marksdailyapple.com/forum/memberslist/

我想从所有页面中获取每个用户名,

我想用 bash 在 linux 中做到这一点

我应该从哪里开始,有人能给我一些建议吗?

4

4 回答 4

7

这就是我的Xidel的用途:

xidel http://www.marksdailyapple.com/forum/memberslist/ -e 'a.username'  -f '(//a[@rel="Next"])[1]'

使用这个简单的行,它将使用适当的 html 解析器解析页面,使用 css 选择器查找所有带有名称的链接,使用 xpath 查找下一页并重复此操作,直到处理完所有页面

您也可以仅使用 css 选择器编写它:

xidel http://www.marksdailyapple.com/forum/memberslist/ -e 'a.username'  -f 'div#pagination_top span.prev_next a'

或者模式匹配。基本上,您只需复制要从页面源中找到的 html 元素,并将文本内容替换为{.}

xidel http://www.marksdailyapple.com/forum/memberslist/ -e '<a class="username">{.}</a>*'  -f '<a rel="next">{.}</a>'
于 2013-10-26T23:08:06.663 回答
2

首先,您应该使用wget来获取所有用户名页面。您将不得不使用一些选项(查看手册页wget)以使其跟随正确的链接,并且最好不要跟随任何无趣的链接(或者如果失败,您可以在之后忽略无趣的链接)。

然后,尽管Stackoverflow 告诉您不要使用正则表达式来解析 HTML,但您应该使用正则表达式来解析 HTML,因为这只是一个家庭作业,对吗?

如果这不是家庭作业,那么您还没有选择最适合这项工作的工具。

于 2013-10-26T19:15:34.623 回答
2

正如 Robin 所建议的那样,你真的应该在包含一个像样的 html 解析器的编程语言中做这种事情。您总是可以使用命令行工具执行各种任务,但是在这种情况下,我可能会选择 perl。

如果您真的想尝试使用命令行工具,我建议您使用 curl、grep、sort 和 sed。

当我有东西可以玩时,我总是觉得它更容易,所以这里有一些东西可以让你开始。
我不会使用这种代码来产生有用的东西,但只是为了让你得到一些想法。

  • memberpages 似乎是 xxx://xxx.xxx/index1.html,其中 1 表示页码。因此,我要做的第一件事就是提取最后一个会员页面的编号。当我拥有它时,我知道我想用哪些 URL 来提供 curl。

  • 每个用户名都属于“用户名”类的成员,有了这些信息,我们可以使用 grep 来获取相关数据。

    #!/bin/bash 
    number_of_pages=2
    curl http://www.marksdailyapple.com/forum/memberslist/index[1-${number_of_pages}].html --silent | egrep 'class="username">.*</a>' -o | sed 's/.*>\(.*\)<\/a>/\1/' | sort     
    

这里的想法是给 curl 以 index[1-XXXX].html 格式的地址,这将使 curl 遍历所有页面。然后我们对用户名类进行 grep,将其传递给 sed 以提取相关数据(用户名)。然后,我们将生成的“用户名列表”传递给 sort 以对用户名进行排序。我总是喜欢排序的东西;)

大笔记虽然,

  1. 你真的应该以另一种方式来做这件事。同样,我推荐 perl 来处理这些任务。
  2. 没有错误检查、用户名验证等。如果你应该在某种生产中使用它,没有捷径,那就做对。尝试阅读如何用不同的编程语言解析网页。
  3. 出于目的,我将 number_of_pages 声明为两个。您必须自己想办法获得最后一个会员页面的编号。虽然它有很多页面,我想它需要一些时间来遍历它们。

希望有帮助!

于 2013-10-26T22:41:43.923 回答
1

我使用这个 bash 脚本浏览了所有页面:

#!/bin/bash

IFS=$'\n'
url="http://www.marksdailyapple.com/forum/memberslist/"
content=$(curl --silent -L ${url} 2>/dev/null | col -b)
pages=$(echo ${content} | sed -n '/Last Page/s/^.*index\([0-9]\+\).*/\1/p' | head -1)
for page in $(seq ${pages}); do
    IFS=
    content=$(curl --silent -L ${url}index${page}.html 2>/dev/null | col -b)
    patterns=$(echo ${content} | sed -n 's/^.*class="username">\([^<]*\)<.*$/\1/gp')
    IFS=$'\n' users=(${patterns})
    for user in ${users[@]}; do
        echo "user=${user}."
    done
done
于 2013-10-27T00:29:17.553 回答