1

Тема: Простенький парсер видачі Google (top 10) : PHP & Python & Java

Давайте створимо парсер, який буде парсити URL 10-ти сторінок з Google по запиту форум програмістів. Результат роботи повинен записуватись в текстовий файл, наприклад log.txt :)
Я почну на Python.

Продовження теми Створення статичної сторінки

Подякували: 221VOLT1

2 Востаннє редагувалося Vo_Vik (14.03.2013 20:46:26)

Re: Простенький парсер видачі Google (top 10) : PHP & Python & Java

Що значить парсити? що повинно бути в результаті? Просто 10 url?

3

Re: Простенький парсер видачі Google (top 10) : PHP & Python & Java

Так
Парсити - Відшукати певну інформацію на сайті/сайтах, зазвичай за допомогою регулярок.

4

Re: Простенький парсер видачі Google (top 10) : PHP & Python & Java

Python:

#!/usr/bin/python
# -*- coding: utf-8 -*- 
#date: March 14, 2013

import urllib2
import re
 
def top10(query = 'форум%20програмістів'):

    user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.160 Safari/537.22'
    headers = { 'User-Agent' : user_agent }
    url = 'http://www.google.com.ua/search?hl=uk&q=' + query
    req = urllib2.Request(url, headers = headers)
    response = urllib2.urlopen(req)
    html = response.read()
    expression = r'<h3 class="r"><a href="([^"]*)"'
    
    matches = re.findall(expression, html)
    if matches:
        f = open('log.txt', 'w')
        for match in matches:
               f.write(match + "\n")
   
def main():
    top10()
   
if __name__ == '__main__':
    main()

log.txt:

http://replace.org.ua/
http://www.programmersforum.ru/
http://tereveni.org/topic/28361/
http://student-lamer.at.ua/forum/
http://linux.org.ua/cgi-bin/yabb/YaBB.pl?num=1344775624
http://sf.nung.edu.ua/lofiversion/index.php/t948.html
http://forum.finance.ua/topic123803.html
http://forum.finance.ua/topic124561.html
http://forum.tntu.edu.ua/index.php?s=886928b002fe4ce3663ce4e6aff21c38&amp;showtopic=10147
http://ce.lviv.ua/catalog/?section_id=34&amp;obj=site&amp;id=38938
Подякували: Vo_Vik, 221VOLT2

5

Re: Простенький парсер видачі Google (top 10) : PHP & Python & Java

php:

function top10($query = 'форум%20програмістів') {
    
    $user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.160 Safari/537.22';
    $url = 'http://www.google.com.ua/search?hl=uk&q=' . $query;
    $data = file_get_contents($url);
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $data = curl_exec($ch);
    curl_close($ch);
    
    $pattern = '#<h3 class="r"><a href="([^"]*)"#';
    preg_match_all($pattern, $data, $matches);
    $matches = $matches[1];
    
    $handle = fopen('log.txt', 'w');
    
    foreach ($matches as $match) {
        fwrite($handle, $match . "\n");
    }
    
    fclose($handle);

}

top10();
Подякували: miroslav.chandler, leofun01, 221VOLT3

6

Re: Простенький парсер видачі Google (top 10) : PHP & Python & Java

Java:

import java.net.*;
import java.io.*;
import java.util.regex.*;

public class Parser {

    public static void main(String args[]) {
        top10("форум%20програмістів");
    }
    
    private static void top10(String query) {
        try {
        
            URL url = new URL("http://www.google.com.ua/search?hl=uk&q=" + query);
            URLConnection hc = url.openConnection();
            hc.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.160 Safari/537.22");
        
            BufferedReader in = new BufferedReader(new InputStreamReader(hc.getInputStream()));
            String inputLine, html = "";
            while ((inputLine = in.readLine()) != null) 
                html += inputLine;
            in.close();
            
            
            Pattern pattern = Pattern.compile("<h3 class=\"r\"><a href=\"([^\"]*)\"");
            Matcher matcher = pattern.matcher(html);
            
            BufferedWriter log = new BufferedWriter(new FileWriter(new File("log.txt")));
            
            while (matcher.find()) {
                log.write(matcher.group(1) + "\n");
            }
            
            log.close();
            
            
        } catch (IOException e) {
            System.out.println(e.toString());
        }
    }

}
Подякували: leofun011

7 Востаннє редагувалося Vo_Vik (15.03.2013 21:24:35)

Re: Простенький парсер видачі Google (top 10) : PHP & Python & Java

Супер, доречі, в php як і в java, можна зробити через лог файл.
Маю наувазі error_log(), але то буде вже трохи збочення)

8

Re: Простенький парсер видачі Google (top 10) : PHP & Python & Java

Сильно не вдумуючись переписав варіант java на с#

using System;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            const string url = @"http://www.google.com.ua/search?hl=uk&q=форум%20програмістів";
            string response;
            using (var wb = new WebClient())
            {
                wb.Headers["User-Agent"] =
                    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31";
                response = wb.DownloadString(url);
            }
            var regex = new Regex("<h3 class=\"r\"><a href=\"([^\"]*)\"");
            var matches = regex.Matches(response);
            using (TextWriter tw = File.CreateText("log.txt"))
            {
                foreach (Match match in matches)
                    tw.WriteLine(match.Groups[1]);
            }
            Console.WriteLine("Done");
            Console.ReadKey();
        }
    }
}

Все тепер можна з чистою душею йти спати :)

Подякували: Replace, leofun012

9 Востаннє редагувалося 221VOLT (Сьогодні 09:51:58)

Re: Простенький парсер видачі Google (top 10) : PHP & Python & Java

Erlang (Erlang/OTP 22 [erts-10.4]), 2 способи --
регулярка -- функція parse_urls1
паттерн матчінг -- функція parse_urls2

все, що нижче функції parse_urls2/3 -- то url_encode
(не знаю, чи цю функцію для utf8 уже додали в OTP, можливо ще ні, лінь шукати)

-module(u10).
-compile([export_all, nowarn_export_all]).

% get 10 urls from google search by request "форум програмістів"

do() ->
  ssl:start(),
  %inets:start(),
  application:start(inets),
  
  get_data().

get_data() ->
  Part = <<"форум програмістів"/utf8>>,
  Url = "https://www.google.com.ua/search?hl=uk&q=" ++ escape_uri(Part),
  %io:format("~p~n",[escape_uri(Part)]),
  Headers = [{"Host", "www.google.com.ua\r\n"},
             {"User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:71.0) Gecko/20100101 Firefox/71.0\r\n"},
             {"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"},
             {"Accept-language", "uk,uk_UA\r\n"}, {"Cookie", "\r\n"}, {"Connection", "keep-alive\r\n"},
             {"Upgrade-Insecure-Requests", "1\r\n"}, {"Cache-Control", "max-age=0\r\n"}],
  case httpc:request(get, {Url, Headers}, [{ssl,[{verify,0}]}], []) of
    {ok,{_Status, _Headers , Content}} ->
      %parse_urls1(Content);
      parse_urls2(Content);
    _ ->
      get_data()
  end.

parse_urls1(Data) ->
  Regex = "<div class=\"r\"><a href=\"([^\"]*)\".*?<h3.*?>(.*?)<\/h3>.*?<\/a>",
  case re:run(Data, Regex, [ global, {capture, all, list}]) of
    { match, MatchList } ->
      lists:foreach(
        fun(El) ->
          El3 = unicode:characters_to_binary( lists:nth(3, El), utf8, latin1), % names
          El2 = unicode:characters_to_binary( lists:nth(2, El), utf8, latin1), % urls
          io:format("~ts~n", [El2]),
          io:format("~ts~n", [El3]),
          %io:format("~ts~n", [El])
          %io:format("~ts~n", [unicode:characters_to_binary([El], utf8, latin1)])
          
          file:write_file("top10_names.txt", io_lib:fwrite("~s", [unicode:characters_to_binary([lists:nth(3, El), "\n"], utf8, latin1)]), [append]),
          file:write_file("top10_urls.txt", io_lib:fwrite("~s", [unicode:characters_to_binary([lists:nth(2, El), "\n"], utf8, latin1)]), [append])
        end,
        MatchList);
  NoMatch ->
    io:format("Nothing found: ~p~n", [NoMatch])
  end.

% mask for search
% <div class="r"><a href="https://replace.org.ua/" onmousedown="return rwt(this,'','','','1','AOvVaw330b2J7_UJPUW_UVnlZHvp','','28ahUKEiorY-Xv6zlAhXFcJoKHUUOBGMsFjAAegQIABAB','','',event)"><h3 class="LC20lb">Український форум програмістів</h3><br><div class="TbwUpd"><cite class="iUh30">https://replace.org.ua</cite></div></a>

parse_urls2(Content) -> parse_urls2( unicode:characters_to_list([Content], utf8), 0, []).

%parse_urls2(Content, Type, Acc) ->
parse_urls2([], _, _) ->
  ssl:stop(),
  %inets:stop(),
  application:stop(inets),
  ok;
parse_urls2([60,100,105,118,32,99,108,97,115,115,61,34,114,34,62,60,
  97,32,104,114,101,102,61,34|T], 0, Acc) -> parse_urls2(T, 1, Acc); % "<div class=\"r\"><a href=\""
parse_urls2([_|T], 0, Acc) -> parse_urls2(T, 0, Acc);
parse_urls2([34|T], 1, Acc) -> % "\""
  Z0 = lists:reverse(Acc),
  Z = unicode:characters_to_binary(Z0, utf8, latin1), % url
  io:format("~ts~n", [Z]),
  file:write_file("top10_urls.txt", io_lib:fwrite("~s", [unicode:characters_to_binary([Z, "\n"], latin1, latin1)]), [append]),
  parse_urls2(T, 2, []);
parse_urls2([H|T], 1, Acc) -> parse_urls2(T, 1, [H|Acc]);
parse_urls2([60,104,51,32,99,108,97,115,115,61,34,76,67,50,48,108,98,
  34,62|T], 2, Acc) -> parse_urls2(T, 3, Acc); % "<h3 class=\"LC20lb\">"
parse_urls2([_|T], 2, Acc) -> parse_urls2(T, 2, Acc);
parse_urls2([60,47,104,51,62|T], 3, Acc) -> % "</h3>"
  Z0 = lists:reverse(Acc),
  Z = unicode:characters_to_binary(Z0, utf8, latin1), % name
  io:format("~ts~n", [Z]),
  file:write_file("top10_names.txt", io_lib:fwrite("~s", [unicode:characters_to_binary([Z, "\n"], latin1, latin1)]), [append]),
  parse_urls2(T, 0, []);
parse_urls2([H|T], 3, Acc) -> parse_urls2(T, 3, [H|Acc]).


escape_uri(<<C, Cs/binary>>) when C >= $a, C =< $z -> <<C, (escape_uri(Cs))/binary>>;
escape_uri(<<C, Cs/binary>>) when C >= $A, C =< $Z -> <<C, (escape_uri(Cs))/binary>>;
escape_uri(<<C, Cs/binary>>) when C >= $0, C =< $9 -> <<C, (escape_uri(Cs))/binary>>;
escape_uri(<<C, Cs/binary>>) when C =:= 32 -> <<"+", (escape_uri(Cs))/binary>>; % space to +
escape_uri(<<C, Cs/binary>>) when C =:= $- -> <<C, (escape_uri(Cs))/binary>>;
escape_uri(<<C, Cs/binary>>) when C =:= $_ -> <<C, (escape_uri(Cs))/binary>>;
escape_uri(<<C, Cs/binary>>) when C =:= 46 -> <<C, (escape_uri(Cs))/binary>>; % .
escape_uri(<<C, Cs/binary>>) when C =:= $! -> <<C, (escape_uri(Cs))/binary>>;
escape_uri(<<C, Cs/binary>>) when C =:= $~ -> <<C, (escape_uri(Cs))/binary>>;
escape_uri(<<C, Cs/binary>>) when C =:= $* -> <<C, (escape_uri(Cs))/binary>>;
escape_uri(<<C, Cs/binary>>) when C =:= 39 -> <<C, (escape_uri(Cs))/binary>>; % '
escape_uri(<<C, Cs/binary>>) when C =:= $( -> <<C, (escape_uri(Cs))/binary>>;
escape_uri(<<C, Cs/binary>>) when C =:= $) -> <<C, (escape_uri(Cs))/binary>>;
escape_uri(<<C, Cs/binary>>) -> <<(escape_byte(C))/binary, (escape_uri(Cs))/binary>>;
escape_uri(<<>>) -> <<>>.
hex_octet(N) when N =< 9 -> $0 + N;
hex_octet(N) when N =< 15 -> $a + N - 10.
escape_byte(C) -> <<"%", (hex_octet(C bsr 4)), (hex_octet(C band 15))>>.

компіляція та запуск

c(u10).
u10:do().

результат

https://replace.org.ua/
https://replace.org.ua/forum/6/
https://dou.ua/forums/
https://linux.org.ua/index.php?topic=1378.0
http://www.cyberforum.ru/
https://zaxid.net/skilki_zaroblyayut_lvivski_programisti_n1419390
https://tereveni.org/topic/28361/
http://www.starbasic.net/httpreplace-org-ua/
https://php.ru/forum/
https://www.programmersforum.ru/


Український форум програмістів
C/C++ - Український форум програмістів
Форум программистов | DOU
Форум програмістів - Linux.org.ua
Форум программистов и сисадминов Киберфорум
Скільки заробляють львівські програмісти - ZAXID.NET
Український форум програмістів - Теревені
Український форум програмістів | StarBasic, основи ...
Форум PHP Программистов | PHP.ru
Форум программистов
Все на світі, як вода, Світла радість і біда.
Все тече і все біжить в нікуди,
Все на світі, як пісок, Залиши на ньому крок,
Змиє все вода, було й так буде.