如何从网页中提取数据(用户名)

时间:2013-10-26 19:04:35

标签: linux bash html-content-extraction

我想从成员列表页面收集用户名,如下所示: http://www.marksdailyapple.com/forum/memberslist/

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

我希望在linux中使用bash

执行此操作

我应该从哪里开始,有人可以给我一些提示吗?

4 个答案:

答案 0 :(得分: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>'

答案 1 :(得分:2)

首先,您应该使用wget来获取所有用户名页面。您将不得不使用一些选项(查看wget的手册页)以使其遵循正确的链接,并且理想情况下不遵循任何不感兴趣的链接(或者失败,您可以忽略之后的无趣链接)

然后,尽管事实Stackoverflow tells you not to use regular expressions to parse HTML,你应该使用正则表达式来解析HTML,因为它只是一个家庭作业,对吗?

如果不是家庭作业,你就没有选择最适合这项工作的工具。

答案 2 :(得分:2)

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

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

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

  • 成员页面似乎是xxx://xxx.xxx/index1.html,其中1表示页码。因此,我要做的第一件事是提取最后一个成员页面的编号。当我知道了哪些网址时,我想知道哪些网址需要卷曲。

  • 每个用户名都在“username”类的成员中,我们可以使用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     
    

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

大笔记,

  1. 你应该以另一种方式做到这一点。同样,我推荐perl用于这些任务。
  2. 没有错误检查,用户名的验证等等。如果你应该在某种生产中使用它,没有捷径,做得对。尝试阅读如何解析不同编程语言的网页。
  3. 根据目的,我将number_of_pages声明为两个。你必须找出一个方法来获取最后一个成员页面的编号。虽然这是很多页面,我想它需要一些时间来迭代它们。
  4. 希望有所帮助!

答案 3 :(得分: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
相关问题