powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Выгрузка данных из web
23 сообщений из 23, страница 1 из 1
Выгрузка данных из web
    #39848280
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте!

Пишу парсинг. Есть такой код на C#. В коде используется XPath.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
using System;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using HtmlAgilityPack;
using HtmlDocument = HtmlAgilityPack.HtmlDocument;

namespace WindowsFormsApp7
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string url = "https://www.sql.ru/forum/dotnet";            

            var pageContent = LoadPage(url);
            var document = new HtmlDocument();
            document.LoadHtml(pageContent);

            //HtmlNodeCollection links = document.DocumentNode.SelectNodes("//table(class,"forumTable"));
            //foreach (HtmlNode link in links)
            // 
        }

        static string LoadPage(string url)
        {
            string result = "";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            if (response.StatusCode == HttpStatusCode.OK)
            {
                Stream receiveStream = response.GetResponseStream();
                if (receiveStream != null)
                {
                    StreamReader readStream;
                    if (response.CharacterSet == null)
                        readStream = new StreamReader(receiveStream);
                    else
                        readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));
                    result = readStream.ReadToEnd();
                    readStream.Close();
                }  
                response.Close();
            }
            return result;
        }
    }
}

В выражении document.DocumentNode.SelectNodes("..."); по разному написал. Не получается выгрузить таблицу. Как правильно написать выражение?
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39848284
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Когда перезагружаешь, то в окне контрольных значений пропадают выражения. Почему так?
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39848287
Фотография Konst_One
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
var n = document.DocumentNode.SelectNode("//*[@class='forumTable']");
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39848302
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Konst_One
Код: c#
1.
var n = document.DocumentNode.SelectNode("//*[@class='forumTable']");

Получилось. Спасибо!
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39848877
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
class CustomDataTypes
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApp7
{
    class CustomDataTypes
    {
        public struct RowTable {
            public String Theme; //Столбец "Тема"
            public String Forum; //Столбец "Форум"
            public String Author; //Столбец "Автор"
            public String Answers; //Столбец "Ответов"
            public String Views; //Столбец "Просмотры"
            public DateTime Date; //Столбец "Дата"

            //Дополнительные поля
            public int TablePageNumber; //Номер "страницы" таблицы
        }
    }
}

class Form1 : Form
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
using System;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using HtmlAgilityPack;
using HtmlDocument = HtmlAgilityPack.HtmlDocument;
using System.Collections.Generic;
using static WindowsFormsApp7.CustomDataTypes;

namespace WindowsFormsApp7
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string url = "https://www.sql.ru/forum/dotnet";           

            var pageContent = LoadPage(url);
            var document = new HtmlDocument();
            document.LoadHtml(pageContent);
            
            HtmlNodeCollection table = document.DocumentNode.SelectNodes("//*[@class='forumTable']");
            HtmlNodeCollection list_tr = table[0].SelectNodes("//tr");

            List < RowTable > list = new List<RowTable>();

            foreach (HtmlNode tr in list_tr)
            {
                RowTable rowTable = new RowTable();

                var th =tr.SelectNodes("//th");

                //rowTable.Theme =...
                //rowTable.Forum = ...
                //rowTable.Answers=...
                //rowTable.Views = ...
                //rowTable.Date = ...

                list.Add(rowTable);                
            }
            
            RowTable[] array = list.ToArray();
        }

        static string LoadPage(string url)
        {
            string result = "";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            if (response.StatusCode == HttpStatusCode.OK)
            {
                Stream receiveStream = response.GetResponseStream();
                if (receiveStream != null)
                {
                    StreamReader readStream;
                    if (response.CharacterSet == null)
                        readStream = new StreamReader(receiveStream);
                    else
                        readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));
                    result = readStream.ReadToEnd();
                    readStream.Close();
                }  
                response.Close();
            }
            return result;
        }
    }
}

Не получается получить значения строк и колонок. Акцент на выделенные строки. Как правильно написать?
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39848920
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SelectNodes тебе вернет коллекцию.
Либо цикл, либо поиск в коллекции

В конце-концов, поставь точку останова, открой Immediate и экспериментируй сколько влезет
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39848969
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
            ...
            HtmlNodeCollection table = document.DocumentNode.SelectNodes("//*[@class='forumTable']");
            HtmlNodeCollection list_tr = table[0].SelectNodes("//tr");
            
            List < RowTable > list = new List<RowTable>();

            foreach (HtmlNode tr in list_tr)
            {
                RowTable rowTable = new RowTable();

                var col = tr.SelectNodes("//th");

                rowTable.Theme = col[1].InnerText;
                rowTable.Author = col[2].InnerText;
                rowTable.Answers = col[3].InnerText;
                rowTable.Views = col[4].InnerText;
                rowTable.Date = col[5].InnerText;

                list.Add(rowTable);                
            }
            ...

Пишу так, но после каждой итерации значения колонок одинаковые. Почему так?
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39848981
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikkзначения колонок одинаковые. Почему так?Потому что ты по одной и той же коллекции елозишьferzmikk
Код: c#
1.
"//th"



ferzmikkВ коде используется XPath.млин, ну возьми почитай ты синтаксис xpath, вот какой смысл использовать метод тыка?
https://msiter.ru/tutorials/xpath/syntax
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849010
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот так получается
С использованием цикла For
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
            ...
            HtmlNodeCollection rows = document.DocumentNode.SelectNodes("//*[@class='forumTable']//tr");

            List < RowTable > list = new List<RowTable>();
            
            for (int i = 1; i < rows.Count; ++i) //Обращаем внимание, что i = 1, а не 0. Исключаем заголовки
            {
                RowTable rowTable = new RowTable();

                var col = rows.SelectNodes("td");                

                rowTable.Theme = col[1].InnerText;
                rowTable.Author = col[2].InnerText;
                rowTable.Answers = col[3].InnerText;
                rowTable.Views = col[4].InnerText;
                rowTable.Date = col[5].InnerText;

                list.Add(rowTable);                
            }

            RowTable[] array = list.ToArray();
            ...

Выгружается.


Но если написать так
С использованием цикла Foreach
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
            ...
            HtmlNodeCollection rows = document.DocumentNode.SelectNodes("//*[@class='forumTable']//tr");

            List < RowTable > list = new List<RowTable>();     


            foreach (HtmlNode row in rows)            
            {
                RowTable rowTable = new RowTable();
                
                var col = row.SelectNodes("td");

                //rowTable.Theme = col[1].InnerText;
                //rowTable.Author = col[2].InnerText;
                //rowTable.Answers = col[3].InnerText;
                //rowTable.Views = col[4].InnerText;
                //rowTable.Date = col[5].InnerText;

                list.Add(rowTable);
            }


            RowTable[] array = list.ToArray();
            ...

В выделенной строке выдает ошибку "System.NullReferenceException: "Ссылка на объект не указывает на экземпляр объекта.""

Почему так? Получатся для XPath не корректно использовать цикл [i]foreach
?
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849034
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И что, у тебя row==null в этот момент? Какая итерация цикла?
Почему при for ты пропускаешь первый элемент, при foreach не пропускаешь?
Что лежит в rows? открой в отладке, посмотри.
Что ты всякую фигню спрашиваешь до того, как попробовать самому. Тебе и так народ перестал отвечать, потому что как можно несколько лет заниматься программированием и не освоить элементарной отладки.
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849080
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Исправил

С использованием цикла For
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
                for (int i = 0; i < rows.Count; ++i) 
                {
                    RowTable rowTable = new RowTable();

                    var col = rows[i].SelectNodes("td");

                    if (col == null) continue;

                    rowTable.Theme = col[1].InnerText;
                    rowTable.Author = col[2].InnerText;
                    rowTable.Answers = col[3].InnerText;
                    rowTable.Views = col[4].InnerText;
                    rowTable.Date = col[5].InnerText;
                    rowTable.TablePageNumber = NumberTablePages;

                    list.Add(rowTable);
                }

С использованием цикла Foreach
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
foreach (HtmlNode row in rows)            
                {
                    RowTable rowTable = new RowTable();

                    var col = row.SelectNodes("td");

                    if (col == null) continue;

                    rowTable.Theme = col[1].InnerText;
                    rowTable.Author = col[2].InnerText;
                    rowTable.Answers = col[3].InnerText;
                    rowTable.Views = col[4].InnerText;
                    rowTable.Date = col[5].InnerText;

                    list.Add(rowTable);
                }

...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849153
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Чтобы не забанили на сайте, где выгружаешь таблицу, разделенную на множество страниц , то актуально в коде указать заголовки. Я правильно понимаю, что достаточно указывать свойства HttpWebRequest.Accept и HttpWebRequest.UserAgent? Правильно понимаю, что значения этих свойств на разных компьютерах одинаковые?

2. Если забанят при какой то выгрузке n-ой странички таблички, то придется выгружать заново. Я правильно понимаю, что после выгрузки после n-1 странички нужно задать паузу на какое то время и продолжать выгрузку? Или между выгрузками задать паузу? Или лучше строки таблицы каждой странички лучше сохранять в отдельный файл или в базу данных? Как лучше сделать?

3. В моменте выгрузки данных по страницам, могут быть разные случаи.

Случай 1. То есть когда добавлялась строка в таблицу и в этот момент парсинг выгружает, скажем, 5-ая страницу, то получается что:
- новая строка так не попала при выгрузке первой страницы
- последняя строка на 5-й странице попадет на первую строку 6-й страницы. Получается эта строка выгрузится два раза.

Случай 2. Или наоборот удалилась строка на второй страничке таблицы. Получается что:
- первая строка 6-ой страницы перемещается в последнюю строку 5-ой страницу. И получается строка не попадает в выгрузку. А удаленная страница попала в выгрузку.

Случай 3. Или строка переместилась вверх или вниз на текущей строке, или на другую страницу.

Какие бывают решения, чтобы уловить такие логические нюансы (сдвиги)?
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849222
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Нет

2. Могут забанить насовсем, могут на время, зависит от целевого сайта. Задание паузы между запросами в идеале - в соответствии со скоростью работы обычного человека.

3. В общем случае, когда идет интенсивная работа с этой таблицей, ты ВООБЩЕ никогда не сможешь получить актуальный срез.
Если есть возможность сортировки по дате создания записи - тут ты хотя бы не пропустишь новые записи (хотя это не застрахует от дублей, на которые надо проверять)
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849229
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,

паузу лучше делать не константную, а переменную случайную
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849237
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman MejtesShocker.Pro,

паузу лучше делать не константную, а переменную случайнуюНе думаю, что это сильно поможет. Антиботы и антидосы, как правило, просто рассчитаны на некий порог между запросами, а случайность и так вносит сама сеть.

Но может быть еще и такой вариант, допустим пауза в одну секунду между каждым запросом устроит антибота, но 100 запросов за 100 секунд будут являться отдельной причиной для бана.
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849383
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikk1. Чтобы не забанили на сайте, где выгружаешь таблицу, разделенную на множество страниц , то актуально в коде указать заголовки. 1.1. Я правильно понимаю, что достаточно указывать свойства HttpWebRequest.Accept и HttpWebRequest.UserAgent? 1.2. Правильно понимаю, что значения этих свойств на разных компьютерах одинаковые? Shocker.Pro1. НетХочу уточнить на какой вопрос Вы отвечаете: 1.1. или 1.2.

Если на 1.1., то какие свойства надо указывать?

Если на 1.2., то какие значения надо задавать? Если нажать на F12 - Network - dotnet - Headers - Request Headers и оттуда берется значения Accept и User-Agent. Отсюда же брать?

Shocker.Pro2. Могут забанить насовсем,Если забанят на совсем, то выгружать можно только с другого компьютера. Верно?
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849438
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikkShocker.Pro1. НетХочу уточнить на какой вопрос Вы отвечаете: 1.1. или 1.2.сорри, я отвечал на 1.2

Для начала прочитать, что же означают эти заголовки и на что они влияют


ferzmikkЕсли забанят на совсем, то выгружать можно только с другого компьютера. Верно?Нет. Забанят IP-адрес
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849480
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProНет. Забанят IP-адрес
Может это в правила внести? Добавить в
https://www.sql.ru/forum/rules.aspx Запрещается:
...
публикация серийных ключей, лицензий, способов взлома ПО и других методов, которые можно квалифицировать как преследуемые по закону;

PS Тупо банить по IP непрактично, практичнее накормить обращения с качающего IP говном, т.е. лить не реальную инфу, а инфу похожую на правду.
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849540
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TPS Тупо банить по IP непрактично, практичнее накормить обращения с качающего IP говном, т.е. лить не реальную инфу, а инфу похожую на правду.1) это не типовой функционал, его придется делать специально, причем под каждый запрос - это уж совершенно непрактично.

2) а что делать людям попавшим под ложное срабатывание и накормленным этим говном? Если в случае обычного антибота человек немного поплюется, введет капчу и продолжит, а тут что делать?
Я, кстати, неоднократно и на разных сайтах, обычными действиями вызывал срабатывания антиботов. Просто быстро с помощью жестов открывал и закрывал вкладки в поисках нужной инфы
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849796
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В таблице поле "Тема" содержит само название темы и ссылку. Для того тчобы выгрузить название и ссылку, добавил строки (выделены).
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
                ...
                var pageContent = LoadPage(url);
                var document = new HtmlDocument();
                document.LoadHtml(pageContent);

                HtmlNodeCollection rows = document.DocumentNode.SelectNodes("//*[@class='forumTable']//tr");      

                foreach (HtmlNode row in rows)            
                {
                    RowTable rowTable = new RowTable();

                    HtmlNodeCollection col = row.SelectNodes("td");

                    if (col == null) continue;
                    
                    HtmlNodeCollection node = col[1].SelectNodes("a[1]/@href");

                    rowTable.Theme = node[0].InnerText;
                    rowTable.Reference = node[0].Attributes["href"].Value;
                    rowTable.Author = col[2].InnerText;
                    rowTable.Answers = col[3].InnerText;
                    rowTable.Views = col[4].InnerText;
                    rowTable.Date = col[5].InnerText;

                    list.Add(rowTable);
                 }
                    ...

Название и ссылка выгружается. Но пытался написать без использования переменной node , а использовать Col[1] .
Код: c#
1.
2.
col[1].SelectNodes("a[1]/@href[@attribute='href']")
col[1].SelectNodes("a[1]/@href[1][@attribute='href']")

Возвращает null .

Как правильно написать?
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39849978
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор
Код: c#
1.
a[1]/@href[1][@attribute='href']


Изучение XPath методом тыка. Оригинально.
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39850518
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По поводу выгрузки файла с использованием классов HttpWebRequest и HttpWebResponse я правильно понимаю, что можно выгрузить только через класс FileStream? Или лучше отдельно использовать класс WebClient?
...
Рейтинг: 0 / 0
Выгрузка данных из web
    #39850547
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikkПо поводу выгрузки файла с использованием классов HttpWebRequest и HttpWebResponse я правильно понимаю, что можно выгрузить только через класс FileStream? Или лучше отдельно использовать класс WebClient?
WebClient это вроде древняя версия HttpClient'а, который сейчас считается Obsolete
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Выгрузка данных из web
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]