質問編集履歴

8

修正

2016/08/27 15:46

投稿

dlrowolleh
dlrowolleh

スコア120

test CHANGED
@@ -1 +1 @@
1
- C言語でHTTP通信でHTMLファイルを取得し、保存することは可能でしょうか?
1
+ C言語でHTTP通信でHTMLファイルを取得し、保存することは可能でしょうか?C言語でクローリングがしたいです。
test CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
 
6
6
 
7
- 早速ですが、私はC言語でWebスクレイピング・Webローリングをしたいと思っております。
7
+ 早速ですが、私はC言語でWebスクレイピング・Webローリングをしたいと思っております。
8
8
 
9
9
 
10
10
 

7

追記

2016/08/27 15:46

投稿

dlrowolleh
dlrowolleh

スコア120

test CHANGED
File without changes
test CHANGED
@@ -543,3 +543,79 @@
543
543
  また、コンパイル時に
544
544
 
545
545
  errorやwarningがあった場合、皆様はどのように解決するときのヒントや初心者が犯しやすいミスがあれば教えていただけましたら幸いです。
546
+
547
+
548
+
549
+ ###追記(2016/08/23)
550
+
551
+
552
+
553
+ 実行結果がうまくいっていないような気がします。
554
+
555
+ ---
556
+
557
+
558
+
559
+ 参考にさせて頂いたプログラム:[[C言語] HTTPクライアントを作ってみる](http://qiita.com/edo_m18/items/cef278d0c14d1371db3b)を実行してみたのですが、以下のような実行結果が得られました。
560
+
561
+ なんだか少し違うような気がするのですが、
562
+
563
+ 実行結果がうまくいっているのかの私では判断ができません。
564
+
565
+ 自信がなく、よくわからず質問してしまって申し訳ありませんが、
566
+
567
+ この実行結果で正しいのでしょうか?
568
+
569
+ ```
570
+
571
+ $ ./a.out
572
+
573
+ http://css-eblog.com/P を取得します。 // http://css-eblog.com/Pを取得しているところが少し疑問です。
574
+
575
+ // http://css-eblog.comになるのではと思いますがどうなのでしょうか…?
576
+
577
+
578
+
579
+ HTTP/1.1 400 Bad Request
580
+
581
+ Date: Sat, 27 Aug 2016 15:23:02 GMT
582
+
583
+ Server: Apache/2.2.31
584
+
585
+ Content-Length: 226
586
+
587
+ Connection: close
588
+
589
+ Content-Type: text/html; charset=iso-8859-1
590
+
591
+
592
+
593
+ <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
594
+
595
+ <html><head>
596
+
597
+ <title>400 Bad Request</title> // http://css-eblog.com/Pだからそんなページはないと言われてしまう?
598
+
599
+ // http://css-eblog.comだったら検索できましたが
600
+
601
+ // http://css-eblog.com/Pでは検索できませんでした。
602
+
603
+ </head><body>
604
+
605
+ <h1>Bad Request</h1>
606
+
607
+ <p>Your browser sent a request that this server could not understand.<br />
608
+
609
+ </p>
610
+
611
+ </body></html>
612
+
613
+ ```
614
+
615
+ 自信がなく、よくわからず質問してしまい、恐縮ですが、
616
+
617
+ http://css-eblog.com/P になってしまう原因は何でしょうか?
618
+
619
+ どうすれば http://css-eblog.com になるでしょうか?
620
+
621
+ 何卒、よろしくお願いします。

6

追記

2016/08/27 15:44

投稿

dlrowolleh
dlrowolleh

スコア120

test CHANGED
File without changes
test CHANGED
@@ -64,7 +64,7 @@
64
64
 
65
65
  ---
66
66
 
67
- ###追記(07/27)
67
+ ###追記(07/27)【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
68
68
 
69
69
  皆様のアドバイスをもとにプログラムを書いています。
70
70
 
@@ -442,7 +442,7 @@
442
442
 
443
443
  ```
444
444
 
445
- ###エラーコード
445
+ ###エラーコード【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
446
446
 
447
447
  > $ gcc -o syakyou syakyou.c
448
448
 
@@ -472,7 +472,7 @@
472
472
 
473
473
 
474
474
 
475
- ###試したこと
475
+ ###試したこと【vimdiff syakyou.c othon.cで解決いたしました】
476
476
 
477
477
  otehon.cはコピペしたテキストプログラム
478
478
 
@@ -482,7 +482,7 @@
482
482
 
483
483
 
484
484
 
485
- ###結果
485
+ ###結果【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
486
486
 
487
487
  otehon.cはインデントが空白
488
488
 
@@ -496,9 +496,9 @@
496
496
 
497
497
  ---
498
498
 
499
- ###追記(08/08)
499
+ ###追記(08/08)【打ち間違いに気がつき解決いたしました】
500
-
500
+
501
- ###warningが出て困っています。どなたか教えていただけないでしょうか
501
+ ###warningが出て困っています。どなたか教えていただけないでしょうか【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
502
502
 
503
503
  > $ gcc syakyou.c
504
504
 
@@ -518,7 +518,7 @@
518
518
 
519
519
 
520
520
 
521
- ###試したこと
521
+ ###試したこと【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
522
522
 
523
523
 
524
524
 

5

追記

2016/08/27 15:14

投稿

dlrowolleh
dlrowolleh

スコア120

test CHANGED
File without changes
test CHANGED
@@ -491,3 +491,55 @@
491
491
  のため、差分の量が多過ぎて見分けがつかず、お手上げです。
492
492
 
493
493
  重ね重ね申し訳ありません。
494
+
495
+
496
+
497
+ ---
498
+
499
+ ###追記(08/08)
500
+
501
+ ###warningが出て困っています。どなたか教えていただけないでしょうか
502
+
503
+ > $ gcc syakyou.c
504
+
505
+ syakyou.c: In function ‘main’:
506
+
507
+ syakyou.c:83:20: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘char *’ [-Wformat=]
508
+
509
+ sprintf(send_buf, "Host: %s:%d\r\n", url.host, url.path); ^
510
+
511
+
512
+
513
+ です。
514
+
515
+ これはどういった意味なのでしょうか?
516
+
517
+ char型なのに %d にしているというということでしょうか?
518
+
519
+
520
+
521
+ ###試したこと
522
+
523
+
524
+
525
+ Chironian様のアドバイスを元に
526
+
527
+ ```c
528
+
529
+ 58 hints.ai_socktyoe = AF_INET; を
530
+
531
+ 58 hints.ai_family = AF_INET; に打ち直しました。
532
+
533
+ url1 を
534
+
535
+ url に直しました。
536
+
537
+ ```
538
+
539
+ よろしくお願いします。
540
+
541
+
542
+
543
+ また、コンパイル時に
544
+
545
+ errorやwarningがあった場合、皆様はどのように解決するときのヒントや初心者が犯しやすいミスがあれば教えていただけましたら幸いです。

4

更新

2016/08/08 06:32

投稿

dlrowolleh
dlrowolleh

スコア120

test CHANGED
File without changes
test CHANGED
@@ -489,3 +489,5 @@
489
489
  syakyou.cはインデントがタブ
490
490
 
491
491
  のため、差分の量が多過ぎて見分けがつかず、お手上げです。
492
+
493
+ 重ね重ね申し訳ありません。

3

更新

2016/07/27 05:58

投稿

dlrowolleh
dlrowolleh

スコア120

test CHANGED
File without changes
test CHANGED
@@ -92,7 +92,7 @@
92
92
 
93
93
 
94
94
 
95
- 参考にさせて頂いたプログラム:[[C言語] HTTPクライアントを作ってみる](http://http://qiita.com/edo_m18/items/cef278d0c14d1371db3b)
95
+ 参考にさせて頂いたプログラム:[[C言語] HTTPクライアントを作ってみる](http://qiita.com/edo_m18/items/cef278d0c14d1371db3b)
96
96
 
97
97
 
98
98
 

2

追記

2016/07/27 05:56

投稿

dlrowolleh
dlrowolleh

スコア120

test CHANGED
File without changes
test CHANGED
@@ -59,3 +59,433 @@
59
59
  どうかお助けください。
60
60
 
61
61
  よろしくお願いいたします。
62
+
63
+
64
+
65
+ ---
66
+
67
+ ###追記(07/27)
68
+
69
+ 皆様のアドバイスをもとにプログラムを書いています。
70
+
71
+ エラーの意味が分からず困っています。
72
+
73
+ 写し間違いだと思うのですが、どこを間違えているのか、エラーの描いてあることがよく分かりません。
74
+
75
+ どなたか解説していただけませか。
76
+
77
+
78
+
79
+ そもそもコードが公開されているのであれば、それをコピーすればいいのかもしれませんが、少しでも理解して身につけたいと思い、コピペはせず、見ながら打ち込むようにしています。
80
+
81
+
82
+
83
+ 効率が最悪かもしれませんが、親切な方がいらっしゃいましたら、このひよっこに暖かい手を差し伸べていただけないでしょうか。
84
+
85
+
86
+
87
+ また、効率の良いやり方・勉強法等をご存知の方がいらっしゃいましたら、併せて教えていただけましたら幸いです。
88
+
89
+
90
+
91
+ よろしくお願いいたします。
92
+
93
+
94
+
95
+ 参考にさせて頂いたプログラム:[[C言語] HTTPクライアントを作ってみる](http://http://qiita.com/edo_m18/items/cef278d0c14d1371db3b)
96
+
97
+
98
+
99
+ ```C
100
+
101
+ //syakyou.c
102
+
103
+ 1 #include <stdio.h>
104
+
105
+ 2 #include <string.h>
106
+
107
+ 3 #include <stdlib.h>
108
+
109
+ 4 #include <sys/types.h>
110
+
111
+ 5 #include <netdb.h>
112
+
113
+ 6 #include <netinet/in.h>
114
+
115
+ 7 #include <sys/param.h>
116
+
117
+ 8 #include <unistd.h>
118
+
119
+ 9
120
+
121
+ 10 #define BUF_LEN 256
122
+
123
+ 11
124
+
125
+ 12 struct URL {
126
+
127
+ 13 char host[BUF_LEN];
128
+
129
+ 14 char path[BUF_LEN];
130
+
131
+ 15 char query[BUF_LEN];
132
+
133
+ 16 char fragment[BUF_LEN];
134
+
135
+ 17 unsigned short port;
136
+
137
+ 18 };
138
+
139
+ 19
140
+
141
+ 20 /**
142
+
143
+ 21 * @param urlStr URLテキスト
144
+
145
+ 22 */
146
+
147
+ 23 void parseURL(const char *urlStr, struct URL *url, char **error);
148
+
149
+ 24
150
+
151
+ 25 int main(int argc, char **argv) {
152
+
153
+ 26
154
+
155
+ 27 //ソケットのためのファイルディスクリプタ
156
+
157
+ 28 int s;
158
+
159
+ 29
160
+
161
+ 30 //IPアドレスの解決
162
+
163
+ 31 struct addrinfo hints, *res;
164
+
165
+ 32 struct in_addr addr;
166
+
167
+ 33 int err;
168
+
169
+ 34
170
+
171
+ 35 //サーバに送るHTTPプロトコル用バッファ
172
+
173
+ 36 char send_buf[BUF_LEN];
174
+
175
+ 37
176
+
177
+ 38 struct URL url1 = {
178
+
179
+ 39 "css-eblog.com","/",80
180
+
181
+ 40 };
182
+
183
+ 41
184
+
185
+ 42 //URLが指定されていたら
186
+
187
+ 43 if(argc>1){
188
+
189
+ 44 char *error = NULL;
190
+
191
+ 45 parseURL(argv[1],&url,&error);
192
+
193
+ 46
194
+
195
+ 47 if(error){
196
+
197
+ 48 printf("%s/n",error);
198
+
199
+ 49 return 1;
200
+
201
+ 50 }
202
+
203
+ 51 }
204
+
205
+ 52
206
+
207
+ 53 printf("http://%s%s%sを取得します。\n\n", url.host, url1.path, url.query);
208
+
209
+ 54
210
+
211
+ 55 //0クリア
212
+
213
+ 56 memset(&hints, 0, sizeof(hints));
214
+
215
+ 57 hints.ai_socktype = SOCK_STREAM;
216
+
217
+ 58 hints.ai_socktyoe = AF_INET;
218
+
219
+ 59
220
+
221
+ 60 char *serviceType = "http";
222
+
223
+ 61
224
+
225
+ 62 if((err = getaddrinfo(url.host, serviceType, &hints, &res)) != 0) {
226
+
227
+ 63 printf("error %d\n", err);
228
+
229
+ 64 return 1;
230
+
231
+ 65 }
232
+
233
+ 66
234
+
235
+ 67 //ソケット生成
236
+
237
+ 68 if((s = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
238
+
239
+ 69 fprintf(stderr, "ソケットの作成に失敗しました。\n");
240
+
241
+ 70 return 1;
242
+
243
+ 71 }
244
+
245
+ 72
246
+
247
+ 73 //サーバに接続
248
+
249
+ 74 if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
250
+
251
+ 75 fprintf(stderr, "connectに失敗しました。\n");
252
+
253
+ 76 return 1;
254
+
255
+ 77 }
256
+
257
+ 78
258
+
259
+ 79 //HTTPプロトコルの開始 &サーバに送信
260
+
261
+ 80 sprintf(send_buf, "GET %s%s HTTP/1.0\r\n", url.path, url.query);
262
+
263
+ 81 write(s, send_buf, strlen(send_buf));
264
+
265
+ 82
266
+
267
+ 83 sprintf(send_buf, "Host: %s:%d\r\n", url.host, url.path);
268
+
269
+ 84 write(s, send_buf, strlen(send_buf));
270
+
271
+ 85
272
+
273
+ 86 sprintf(send_buf, "\r\n");
274
+
275
+ 87 write(s, send_buf, strlen(send_buf));
276
+
277
+ 88
278
+
279
+ 89 //受信が終わるまでループ
280
+
281
+ 90 while(1){
282
+
283
+ 91 char buf[BUF_LEN];
284
+
285
+ 92 int read_size;
286
+
287
+ 93 read_size = read(s, buf, BUF_LEN);
288
+
289
+ 94
290
+
291
+ 95 if(read_size > 0) {
292
+
293
+ 96 write(1, buf, read_size);
294
+
295
+ 97 }
296
+
297
+ 98 else{
298
+
299
+ 99 break;
300
+
301
+ 100 }
302
+
303
+ 101 }
304
+
305
+ 102
306
+
307
+ 103 //ソケットを閉じる
308
+
309
+ 104 close(s);
310
+
311
+ 105
312
+
313
+ 106 return 0;
314
+
315
+ 107 }
316
+
317
+ 108
318
+
319
+ 109
320
+
321
+ 110 void parseURL(const char *urlStr, struct URL *url, char **error) {
322
+
323
+ 111 char host_path[BUF_LEN];
324
+
325
+ 112
326
+
327
+ 113 if(strlen(urlStr) > BUF_LEN - 1) {
328
+
329
+ 114 *error = "URLが長すぎます。\n";
330
+
331
+ 115 return;
332
+
333
+ 116 }
334
+
335
+ 117
336
+
337
+ 118 //http://から始まる文字列で
338
+
339
+ 119 //sscanfが成功して
340
+
341
+ 120 //http://のあとに何かの文字列が存在するなら
342
+
343
+ 121 if(strstr(urlStr, "http://") &&
344
+
345
+ 122 sscanf(urlStr, "http://%s", host_path) &&
346
+
347
+ 123 strcmp(urlStr, "http://")){
348
+
349
+ 124
350
+
351
+ 125 char *p = NULL;
352
+
353
+ 126
354
+
355
+ 127 p = strchr(host_path, '#');
356
+
357
+ 128 if(p != NULL){
358
+
359
+ 129 strcpy(url->fragment, p);
360
+
361
+ 130 *p = '\0';
362
+
363
+ 131 }
364
+
365
+ 132
366
+
367
+ 133 p = strchr(host_path, '?');
368
+
369
+ 134 if(p != NULL){
370
+
371
+ 135 strcpy(url->query, p);
372
+
373
+ 136 *p = '\0';
374
+
375
+ 137 }
376
+
377
+ 138
378
+
379
+ 139 p = strchr(host_path, '/');
380
+
381
+ 140 if(p != NULL){
382
+
383
+ 141 strcpy(url->path, p);
384
+
385
+ 142 *p = '\0';
386
+
387
+ 143 }
388
+
389
+ 144
390
+
391
+ 145 strcpy(url->host, host_path);
392
+
393
+ 146
394
+
395
+ 147 //ホスト名の部分に":"が含まれていたら
396
+
397
+ 148 p = strchr(url1->host, ':');
398
+
399
+ 149 if(p != NULL){
400
+
401
+ 150 //ポート番号を取得
402
+
403
+ 151 url->port = atoi(p + 1);
404
+
405
+ 152
406
+
407
+ 153 //数字ではない(atoiが失敗)か、0だったら
408
+
409
+ 154 //ポート番号は80に決め打ち
410
+
411
+ 155 if(url->port <= 0) {
412
+
413
+ 156 url->port = 80;
414
+
415
+ 157 }
416
+
417
+ 158
418
+
419
+ 159 //終端文字で空にする
420
+
421
+ 160 *p = '\0';
422
+
423
+ 161 }
424
+
425
+ 162 else{
426
+
427
+ 163 url->port = 80;
428
+
429
+ 164 }
430
+
431
+ 165 }
432
+
433
+ 166 else{
434
+
435
+ 167 *error = "URLはhttp://host/pathの形式で指定してください。\n";
436
+
437
+ 168 return;
438
+
439
+ 169 }
440
+
441
+ 170 }
442
+
443
+ ```
444
+
445
+ ###エラーコード
446
+
447
+ > $ gcc -o syakyou syakyou.c
448
+
449
+ syakyou.c: In function ‘main’:
450
+
451
+ syakyou.c:45:21: error: ‘url’ undeclared (first use in this function)
452
+
453
+ parseURL(argv[1],&url,&error);
454
+
455
+ ^
456
+
457
+ syakyou.c:45:21: note: each undeclared identifier is reported only once for each function it appears in
458
+
459
+ syakyou.c:58:7: error: ‘struct addrinfo’ has no member named ‘ai_socktyoe’
460
+
461
+ hints.ai_socktyoe = AF_INET;
462
+
463
+ ^
464
+
465
+ syakyou.c: In function ‘parseURL’:
466
+
467
+ syakyou.c:148:14: error: ‘url1’ undeclared (first use in this function)
468
+
469
+ p = strchr(url1->host, ':');
470
+
471
+ ^
472
+
473
+
474
+
475
+ ###試したこと
476
+
477
+ otehon.cはコピペしたテキストプログラム
478
+
479
+ syakyou.cは見ながら写したプログラム
480
+
481
+ > $ diff syakyou.c otehon.c
482
+
483
+
484
+
485
+ ###結果
486
+
487
+ otehon.cはインデントが空白
488
+
489
+ syakyou.cはインデントがタブ
490
+
491
+ のため、差分の量が多過ぎて見分けがつかず、お手上げです。

1

2016/07/27 05:54

投稿

dlrowolleh
dlrowolleh

スコア120

test CHANGED
File without changes
test CHANGED
@@ -46,6 +46,16 @@
46
46
 
47
47
 
48
48
 
49
+ これだけでは分からない部分もたくさんあると思います。
50
+
51
+
52
+
53
+ 自分でも分からないことがたくさんあるので追記などで対応していきます。
54
+
55
+
56
+
57
+
58
+
49
59
  どうかお助けください。
50
60
 
51
61
  よろしくお願いいたします。