質問編集履歴
8
修正
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
C言語でHTTP通信でHTMLファイルを取得し、保存することは可能でしょうか?
|
1
|
+
C言語でHTTP通信でHTMLファイルを取得し、保存することは可能でしょうか?C言語でクローリングがしたいです。
|
body
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
初心者です。
|
2
2
|
よろしくお願いいいたします。
|
3
3
|
|
4
|
-
早速ですが、私はC言語でWebスクレイピング・
|
4
|
+
早速ですが、私はC言語でWebスクレイピング・Webクローリングをしたいと思っております。
|
5
5
|
|
6
6
|
|
7
7
|
WebスクレイピングやWebクローリングについて自分自身、調べたりしたところ、PHPやpython、perl、ruby、shellscriptなどのスクリプト言語を用いるのが普通のようでした。
|
7
追記
title
CHANGED
File without changes
|
body
CHANGED
@@ -270,4 +270,42 @@
|
|
270
270
|
よろしくお願いします。
|
271
271
|
|
272
272
|
また、コンパイル時に
|
273
|
-
errorやwarningがあった場合、皆様はどのように解決するときのヒントや初心者が犯しやすいミスがあれば教えていただけましたら幸いです。
|
273
|
+
errorやwarningがあった場合、皆様はどのように解決するときのヒントや初心者が犯しやすいミスがあれば教えていただけましたら幸いです。
|
274
|
+
|
275
|
+
###追記(2016/08/23)
|
276
|
+
|
277
|
+
実行結果がうまくいっていないような気がします。
|
278
|
+
---
|
279
|
+
|
280
|
+
参考にさせて頂いたプログラム:[[C言語] HTTPクライアントを作ってみる](http://qiita.com/edo_m18/items/cef278d0c14d1371db3b)を実行してみたのですが、以下のような実行結果が得られました。
|
281
|
+
なんだか少し違うような気がするのですが、
|
282
|
+
実行結果がうまくいっているのかの私では判断ができません。
|
283
|
+
自信がなく、よくわからず質問してしまって申し訳ありませんが、
|
284
|
+
この実行結果で正しいのでしょうか?
|
285
|
+
```
|
286
|
+
$ ./a.out
|
287
|
+
http://css-eblog.com/P を取得します。 // http://css-eblog.com/Pを取得しているところが少し疑問です。
|
288
|
+
// http://css-eblog.comになるのではと思いますがどうなのでしょうか…?
|
289
|
+
|
290
|
+
HTTP/1.1 400 Bad Request
|
291
|
+
Date: Sat, 27 Aug 2016 15:23:02 GMT
|
292
|
+
Server: Apache/2.2.31
|
293
|
+
Content-Length: 226
|
294
|
+
Connection: close
|
295
|
+
Content-Type: text/html; charset=iso-8859-1
|
296
|
+
|
297
|
+
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
298
|
+
<html><head>
|
299
|
+
<title>400 Bad Request</title> // http://css-eblog.com/Pだからそんなページはないと言われてしまう?
|
300
|
+
// http://css-eblog.comだったら検索できましたが
|
301
|
+
// http://css-eblog.com/Pでは検索できませんでした。
|
302
|
+
</head><body>
|
303
|
+
<h1>Bad Request</h1>
|
304
|
+
<p>Your browser sent a request that this server could not understand.<br />
|
305
|
+
</p>
|
306
|
+
</body></html>
|
307
|
+
```
|
308
|
+
自信がなく、よくわからず質問してしまい、恐縮ですが、
|
309
|
+
http://css-eblog.com/P になってしまう原因は何でしょうか?
|
310
|
+
どうすれば http://css-eblog.com になるでしょうか?
|
311
|
+
何卒、よろしくお願いします。
|
6
追記
title
CHANGED
File without changes
|
body
CHANGED
@@ -31,7 +31,7 @@
|
|
31
31
|
よろしくお願いいたします。
|
32
32
|
|
33
33
|
---
|
34
|
-
###追記(07/27)
|
34
|
+
###追記(07/27)【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
|
35
35
|
皆様のアドバイスをもとにプログラムを書いています。
|
36
36
|
エラーの意味が分からず困っています。
|
37
37
|
写し間違いだと思うのですが、どこを間違えているのか、エラーの描いてあることがよく分かりません。
|
@@ -220,7 +220,7 @@
|
|
220
220
|
169 }
|
221
221
|
170 }
|
222
222
|
```
|
223
|
-
###エラーコード
|
223
|
+
###エラーコード【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
|
224
224
|
> $ gcc -o syakyou syakyou.c
|
225
225
|
syakyou.c: In function ‘main’:
|
226
226
|
syakyou.c:45:21: error: ‘url’ undeclared (first use in this function)
|
@@ -235,20 +235,20 @@
|
|
235
235
|
p = strchr(url1->host, ':');
|
236
236
|
^
|
237
237
|
|
238
|
-
###試したこと
|
238
|
+
###試したこと【vimdiff syakyou.c othon.cで解決いたしました】
|
239
239
|
otehon.cはコピペしたテキストプログラム
|
240
240
|
syakyou.cは見ながら写したプログラム
|
241
241
|
> $ diff syakyou.c otehon.c
|
242
242
|
|
243
|
-
###結果
|
243
|
+
###結果【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
|
244
244
|
otehon.cはインデントが空白
|
245
245
|
syakyou.cはインデントがタブ
|
246
246
|
のため、差分の量が多過ぎて見分けがつかず、お手上げです。
|
247
247
|
重ね重ね申し訳ありません。
|
248
248
|
|
249
249
|
---
|
250
|
-
###追記(08/08)
|
250
|
+
###追記(08/08)【打ち間違いに気がつき解決いたしました】
|
251
|
-
###warningが出て困っています。どなたか教えていただけないでしょうか
|
251
|
+
###warningが出て困っています。どなたか教えていただけないでしょうか【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
|
252
252
|
> $ gcc syakyou.c
|
253
253
|
syakyou.c: In function ‘main’:
|
254
254
|
syakyou.c:83:20: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘char *’ [-Wformat=]
|
@@ -258,7 +258,7 @@
|
|
258
258
|
これはどういった意味なのでしょうか?
|
259
259
|
char型なのに %d にしているというということでしょうか?
|
260
260
|
|
261
|
-
###試したこと
|
261
|
+
###試したこと【vimdiff syakyou.c othon.cで打ち間違いに気がつき解決いたしました】
|
262
262
|
|
263
263
|
Chironian様のアドバイスを元に
|
264
264
|
```c
|
5
追記
title
CHANGED
File without changes
|
body
CHANGED
@@ -244,4 +244,30 @@
|
|
244
244
|
otehon.cはインデントが空白
|
245
245
|
syakyou.cはインデントがタブ
|
246
246
|
のため、差分の量が多過ぎて見分けがつかず、お手上げです。
|
247
|
-
重ね重ね申し訳ありません。
|
247
|
+
重ね重ね申し訳ありません。
|
248
|
+
|
249
|
+
---
|
250
|
+
###追記(08/08)
|
251
|
+
###warningが出て困っています。どなたか教えていただけないでしょうか
|
252
|
+
> $ gcc syakyou.c
|
253
|
+
syakyou.c: In function ‘main’:
|
254
|
+
syakyou.c:83:20: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘char *’ [-Wformat=]
|
255
|
+
sprintf(send_buf, "Host: %s:%d\r\n", url.host, url.path); ^
|
256
|
+
|
257
|
+
です。
|
258
|
+
これはどういった意味なのでしょうか?
|
259
|
+
char型なのに %d にしているというということでしょうか?
|
260
|
+
|
261
|
+
###試したこと
|
262
|
+
|
263
|
+
Chironian様のアドバイスを元に
|
264
|
+
```c
|
265
|
+
58 hints.ai_socktyoe = AF_INET; を
|
266
|
+
58 hints.ai_family = AF_INET; に打ち直しました。
|
267
|
+
url1 を
|
268
|
+
url に直しました。
|
269
|
+
```
|
270
|
+
よろしくお願いします。
|
271
|
+
|
272
|
+
また、コンパイル時に
|
273
|
+
errorやwarningがあった場合、皆様はどのように解決するときのヒントや初心者が犯しやすいミスがあれば教えていただけましたら幸いです。
|
4
更新
title
CHANGED
File without changes
|
body
CHANGED
@@ -243,4 +243,5 @@
|
|
243
243
|
###結果
|
244
244
|
otehon.cはインデントが空白
|
245
245
|
syakyou.cはインデントがタブ
|
246
|
-
のため、差分の量が多過ぎて見分けがつかず、お手上げです。
|
246
|
+
のため、差分の量が多過ぎて見分けがつかず、お手上げです。
|
247
|
+
重ね重ね申し訳ありません。
|
3
更新
title
CHANGED
File without changes
|
body
CHANGED
@@ -45,7 +45,7 @@
|
|
45
45
|
|
46
46
|
よろしくお願いいたします。
|
47
47
|
|
48
|
-
参考にさせて頂いたプログラム:[[C言語] HTTPクライアントを作ってみる](http://
|
48
|
+
参考にさせて頂いたプログラム:[[C言語] HTTPクライアントを作ってみる](http://qiita.com/edo_m18/items/cef278d0c14d1371db3b)
|
49
49
|
|
50
50
|
```C
|
51
51
|
//syakyou.c
|
2
追記
title
CHANGED
File without changes
|
body
CHANGED
@@ -28,4 +28,219 @@
|
|
28
28
|
|
29
29
|
|
30
30
|
どうかお助けください。
|
31
|
-
よろしくお願いいたします。
|
31
|
+
よろしくお願いいたします。
|
32
|
+
|
33
|
+
---
|
34
|
+
###追記(07/27)
|
35
|
+
皆様のアドバイスをもとにプログラムを書いています。
|
36
|
+
エラーの意味が分からず困っています。
|
37
|
+
写し間違いだと思うのですが、どこを間違えているのか、エラーの描いてあることがよく分かりません。
|
38
|
+
どなたか解説していただけませか。
|
39
|
+
|
40
|
+
そもそもコードが公開されているのであれば、それをコピーすればいいのかもしれませんが、少しでも理解して身につけたいと思い、コピペはせず、見ながら打ち込むようにしています。
|
41
|
+
|
42
|
+
効率が最悪かもしれませんが、親切な方がいらっしゃいましたら、このひよっこに暖かい手を差し伸べていただけないでしょうか。
|
43
|
+
|
44
|
+
また、効率の良いやり方・勉強法等をご存知の方がいらっしゃいましたら、併せて教えていただけましたら幸いです。
|
45
|
+
|
46
|
+
よろしくお願いいたします。
|
47
|
+
|
48
|
+
参考にさせて頂いたプログラム:[[C言語] HTTPクライアントを作ってみる](http://http://qiita.com/edo_m18/items/cef278d0c14d1371db3b)
|
49
|
+
|
50
|
+
```C
|
51
|
+
//syakyou.c
|
52
|
+
1 #include <stdio.h>
|
53
|
+
2 #include <string.h>
|
54
|
+
3 #include <stdlib.h>
|
55
|
+
4 #include <sys/types.h>
|
56
|
+
5 #include <netdb.h>
|
57
|
+
6 #include <netinet/in.h>
|
58
|
+
7 #include <sys/param.h>
|
59
|
+
8 #include <unistd.h>
|
60
|
+
9
|
61
|
+
10 #define BUF_LEN 256
|
62
|
+
11
|
63
|
+
12 struct URL {
|
64
|
+
13 char host[BUF_LEN];
|
65
|
+
14 char path[BUF_LEN];
|
66
|
+
15 char query[BUF_LEN];
|
67
|
+
16 char fragment[BUF_LEN];
|
68
|
+
17 unsigned short port;
|
69
|
+
18 };
|
70
|
+
19
|
71
|
+
20 /**
|
72
|
+
21 * @param urlStr URLテキスト
|
73
|
+
22 */
|
74
|
+
23 void parseURL(const char *urlStr, struct URL *url, char **error);
|
75
|
+
24
|
76
|
+
25 int main(int argc, char **argv) {
|
77
|
+
26
|
78
|
+
27 //ソケットのためのファイルディスクリプタ
|
79
|
+
28 int s;
|
80
|
+
29
|
81
|
+
30 //IPアドレスの解決
|
82
|
+
31 struct addrinfo hints, *res;
|
83
|
+
32 struct in_addr addr;
|
84
|
+
33 int err;
|
85
|
+
34
|
86
|
+
35 //サーバに送るHTTPプロトコル用バッファ
|
87
|
+
36 char send_buf[BUF_LEN];
|
88
|
+
37
|
89
|
+
38 struct URL url1 = {
|
90
|
+
39 "css-eblog.com","/",80
|
91
|
+
40 };
|
92
|
+
41
|
93
|
+
42 //URLが指定されていたら
|
94
|
+
43 if(argc>1){
|
95
|
+
44 char *error = NULL;
|
96
|
+
45 parseURL(argv[1],&url,&error);
|
97
|
+
46
|
98
|
+
47 if(error){
|
99
|
+
48 printf("%s/n",error);
|
100
|
+
49 return 1;
|
101
|
+
50 }
|
102
|
+
51 }
|
103
|
+
52
|
104
|
+
53 printf("http://%s%s%sを取得します。\n\n", url.host, url1.path, url.query);
|
105
|
+
54
|
106
|
+
55 //0クリア
|
107
|
+
56 memset(&hints, 0, sizeof(hints));
|
108
|
+
57 hints.ai_socktype = SOCK_STREAM;
|
109
|
+
58 hints.ai_socktyoe = AF_INET;
|
110
|
+
59
|
111
|
+
60 char *serviceType = "http";
|
112
|
+
61
|
113
|
+
62 if((err = getaddrinfo(url.host, serviceType, &hints, &res)) != 0) {
|
114
|
+
63 printf("error %d\n", err);
|
115
|
+
64 return 1;
|
116
|
+
65 }
|
117
|
+
66
|
118
|
+
67 //ソケット生成
|
119
|
+
68 if((s = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
|
120
|
+
69 fprintf(stderr, "ソケットの作成に失敗しました。\n");
|
121
|
+
70 return 1;
|
122
|
+
71 }
|
123
|
+
72
|
124
|
+
73 //サーバに接続
|
125
|
+
74 if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
|
126
|
+
75 fprintf(stderr, "connectに失敗しました。\n");
|
127
|
+
76 return 1;
|
128
|
+
77 }
|
129
|
+
78
|
130
|
+
79 //HTTPプロトコルの開始 &サーバに送信
|
131
|
+
80 sprintf(send_buf, "GET %s%s HTTP/1.0\r\n", url.path, url.query);
|
132
|
+
81 write(s, send_buf, strlen(send_buf));
|
133
|
+
82
|
134
|
+
83 sprintf(send_buf, "Host: %s:%d\r\n", url.host, url.path);
|
135
|
+
84 write(s, send_buf, strlen(send_buf));
|
136
|
+
85
|
137
|
+
86 sprintf(send_buf, "\r\n");
|
138
|
+
87 write(s, send_buf, strlen(send_buf));
|
139
|
+
88
|
140
|
+
89 //受信が終わるまでループ
|
141
|
+
90 while(1){
|
142
|
+
91 char buf[BUF_LEN];
|
143
|
+
92 int read_size;
|
144
|
+
93 read_size = read(s, buf, BUF_LEN);
|
145
|
+
94
|
146
|
+
95 if(read_size > 0) {
|
147
|
+
96 write(1, buf, read_size);
|
148
|
+
97 }
|
149
|
+
98 else{
|
150
|
+
99 break;
|
151
|
+
100 }
|
152
|
+
101 }
|
153
|
+
102
|
154
|
+
103 //ソケットを閉じる
|
155
|
+
104 close(s);
|
156
|
+
105
|
157
|
+
106 return 0;
|
158
|
+
107 }
|
159
|
+
108
|
160
|
+
109
|
161
|
+
110 void parseURL(const char *urlStr, struct URL *url, char **error) {
|
162
|
+
111 char host_path[BUF_LEN];
|
163
|
+
112
|
164
|
+
113 if(strlen(urlStr) > BUF_LEN - 1) {
|
165
|
+
114 *error = "URLが長すぎます。\n";
|
166
|
+
115 return;
|
167
|
+
116 }
|
168
|
+
117
|
169
|
+
118 //http://から始まる文字列で
|
170
|
+
119 //sscanfが成功して
|
171
|
+
120 //http://のあとに何かの文字列が存在するなら
|
172
|
+
121 if(strstr(urlStr, "http://") &&
|
173
|
+
122 sscanf(urlStr, "http://%s", host_path) &&
|
174
|
+
123 strcmp(urlStr, "http://")){
|
175
|
+
124
|
176
|
+
125 char *p = NULL;
|
177
|
+
126
|
178
|
+
127 p = strchr(host_path, '#');
|
179
|
+
128 if(p != NULL){
|
180
|
+
129 strcpy(url->fragment, p);
|
181
|
+
130 *p = '\0';
|
182
|
+
131 }
|
183
|
+
132
|
184
|
+
133 p = strchr(host_path, '?');
|
185
|
+
134 if(p != NULL){
|
186
|
+
135 strcpy(url->query, p);
|
187
|
+
136 *p = '\0';
|
188
|
+
137 }
|
189
|
+
138
|
190
|
+
139 p = strchr(host_path, '/');
|
191
|
+
140 if(p != NULL){
|
192
|
+
141 strcpy(url->path, p);
|
193
|
+
142 *p = '\0';
|
194
|
+
143 }
|
195
|
+
144
|
196
|
+
145 strcpy(url->host, host_path);
|
197
|
+
146
|
198
|
+
147 //ホスト名の部分に":"が含まれていたら
|
199
|
+
148 p = strchr(url1->host, ':');
|
200
|
+
149 if(p != NULL){
|
201
|
+
150 //ポート番号を取得
|
202
|
+
151 url->port = atoi(p + 1);
|
203
|
+
152
|
204
|
+
153 //数字ではない(atoiが失敗)か、0だったら
|
205
|
+
154 //ポート番号は80に決め打ち
|
206
|
+
155 if(url->port <= 0) {
|
207
|
+
156 url->port = 80;
|
208
|
+
157 }
|
209
|
+
158
|
210
|
+
159 //終端文字で空にする
|
211
|
+
160 *p = '\0';
|
212
|
+
161 }
|
213
|
+
162 else{
|
214
|
+
163 url->port = 80;
|
215
|
+
164 }
|
216
|
+
165 }
|
217
|
+
166 else{
|
218
|
+
167 *error = "URLはhttp://host/pathの形式で指定してください。\n";
|
219
|
+
168 return;
|
220
|
+
169 }
|
221
|
+
170 }
|
222
|
+
```
|
223
|
+
###エラーコード
|
224
|
+
> $ gcc -o syakyou syakyou.c
|
225
|
+
syakyou.c: In function ‘main’:
|
226
|
+
syakyou.c:45:21: error: ‘url’ undeclared (first use in this function)
|
227
|
+
parseURL(argv[1],&url,&error);
|
228
|
+
^
|
229
|
+
syakyou.c:45:21: note: each undeclared identifier is reported only once for each function it appears in
|
230
|
+
syakyou.c:58:7: error: ‘struct addrinfo’ has no member named ‘ai_socktyoe’
|
231
|
+
hints.ai_socktyoe = AF_INET;
|
232
|
+
^
|
233
|
+
syakyou.c: In function ‘parseURL’:
|
234
|
+
syakyou.c:148:14: error: ‘url1’ undeclared (first use in this function)
|
235
|
+
p = strchr(url1->host, ':');
|
236
|
+
^
|
237
|
+
|
238
|
+
###試したこと
|
239
|
+
otehon.cはコピペしたテキストプログラム
|
240
|
+
syakyou.cは見ながら写したプログラム
|
241
|
+
> $ diff syakyou.c otehon.c
|
242
|
+
|
243
|
+
###結果
|
244
|
+
otehon.cはインデントが空白
|
245
|
+
syakyou.cはインデントがタブ
|
246
|
+
のため、差分の量が多過ぎて見分けがつかず、お手上げです。
|
1
title
CHANGED
File without changes
|
body
CHANGED
@@ -22,5 +22,10 @@
|
|
22
22
|
と実行すると、
|
23
23
|
実行したパソコンの自分で指定したディレクトリにHTMLファイルが保存されるというものです。
|
24
24
|
|
25
|
+
これだけでは分からない部分もたくさんあると思います。
|
26
|
+
|
27
|
+
自分でも分からないことがたくさんあるので追記などで対応していきます。
|
28
|
+
|
29
|
+
|
25
30
|
どうかお助けください。
|
26
31
|
よろしくお願いいたします。
|