├── .gitignore
├── README.md
├── img
├── .DS_Store
└── maingui.jpg
└── weiboPicDownloader
├── pom.xml
└── src
└── main
└── java
└── weibo
├── DateChooser.java
├── FileUtils.java
├── ImageDownloadTask.java
├── MainGui.java
├── WeiboDownloader.java
└── WeiboUtils.java
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 | .idea
3 | .settings
4 | .classpath
5 | .project
6 | target
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 免登录下载微博图片
2 |
3 | 批量下载特定用户的高清大图。
4 |
5 | ## 用法
6 |
7 | 编译,使用`MainGui`主类运行
8 |
9 | 
10 | 1. ~~按照需求点入相应的信息~~ 由于微博接口变动 目前支持根据ID下载
11 | 2. 如果对账号类型有疑问的话,可以参考[我的博客](https://www.cnblogs.com/yanximin/p/10982235.html)
12 | 3. 等待下载完成即可. So Easy!
13 |
14 | ## 更新说明
15 | - 2017年9月18日
16 | - 修复显示文件下载目录时出现的ID重复问题
17 | - 优化代码
18 | - 服务器上没有后缀名的图片默认设置为`jpg`格式
19 | - 2017年9月17日
20 | - 重构代码
21 | - 增加了多线程下载,下图的速度更快了~
22 | - 修复下载GIF图片时后缀不显示为`gif`的问题
23 | - 2018年3月8日
24 | - 根据[Issue#6](https://github.com/yAnXImIN/weiboPicDownloader/issues/6)的反馈,修正图片URL获取方式。感谢反馈者**idtolerate**!他发现了问题并且提出了修复代码
25 | - 重新编译了可执行JAR文件。注意该文件需要在JDK 1.7+上才能运行
26 | - 2019年10月24日
27 | - 增加GUI,操作更加人性化。
28 | - 新增时间选择
29 | - 修复几处BUG
30 | - 采用JDK8编译
31 | - 2019年12月26日
32 | - 修复微博数量过多导致的崩溃
33 | - 2021年7月31日
34 | - 去除不支持的下载类型,去除bin文件,执行需要自行编译
35 |
36 | ## Python移植版本
37 | [ningshu/weiboPicDownloader](https://github.com/ningshu/weiboPicDownloader)
38 | [nondanee/weiboPicDownloader](https://github.com/nondanee/weiboPicDownloader)
39 |
40 | 点个Star再走呗~
41 | 欢迎Fork, 或者PR
42 |
--------------------------------------------------------------------------------
/img/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yAnXImIN/weiboPicDownloader/25143a1ddaa4b6ab705869c0af5b31163a72e433/img/.DS_Store
--------------------------------------------------------------------------------
/img/maingui.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yAnXImIN/weiboPicDownloader/25143a1ddaa4b6ab705869c0af5b31163a72e433/img/maingui.jpg
--------------------------------------------------------------------------------
/weiboPicDownloader/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | yxm
5 | weiboPicDownloader
6 | 0.0.1-SNAPSHOT
7 |
8 |
9 | org.apache.httpcomponents
10 | httpmime
11 | 4.5.3
12 |
13 |
14 | com.google.code.gson
15 | gson
16 | 2.8.1
17 |
18 |
19 | commons-io
20 | commons-io
21 | 2.7
22 |
23 |
24 |
25 |
26 |
27 | org.apache.maven.plugins
28 | maven-compiler-plugin
29 |
30 | 1.8
31 | 1.8
32 | utf-8
33 |
34 |
35 |
36 |
37 |
38 |
39 | 1.8
40 | 1.8
41 |
42 |
--------------------------------------------------------------------------------
/weiboPicDownloader/src/main/java/weibo/DateChooser.java:
--------------------------------------------------------------------------------
1 | package weibo;
2 |
3 | /**
4 |
5 | * ClassName:DateChooser
6 |
7 | * Copyright: copyright (c)2012
8 |
9 | * @author Deng Zhiguang
10 |
11 | * http://zgdeng.iteye.com
12 |
13 | * @Date 2012-2-7
14 |
15 | * Modification History:
16 |
17 | * Date Author Version Reason
18 |
19 | * ------------------------------------------
20 |
21 | */
22 |
23 | import java.awt.BasicStroke;
24 |
25 | import java.awt.BorderLayout;
26 |
27 | import java.awt.Color;
28 |
29 | import java.awt.Component;
30 |
31 | import java.awt.Cursor;
32 |
33 | import java.awt.Dimension;
34 |
35 | import java.awt.Font;
36 |
37 | import java.awt.Graphics;
38 |
39 | import java.awt.Graphics2D;
40 |
41 | import java.awt.GridLayout;
42 |
43 | import java.awt.Point;
44 |
45 | import java.awt.Polygon;
46 |
47 | import java.awt.Stroke;
48 |
49 | import java.awt.Toolkit;
50 |
51 | import java.awt.event.FocusEvent;
52 |
53 | import java.awt.event.FocusListener;
54 |
55 | import java.awt.event.MouseAdapter;
56 |
57 | import java.awt.event.MouseEvent;
58 |
59 | import java.awt.event.MouseListener;
60 |
61 | import java.awt.event.MouseMotionListener;
62 |
63 | import java.text.SimpleDateFormat;
64 |
65 | import java.util.ArrayList;
66 |
67 | import java.util.Calendar;
68 |
69 | import java.util.Comparator;
70 |
71 | import java.util.Date;
72 |
73 | import java.util.List;
74 |
75 |
76 |
77 | import javax.swing.BorderFactory;
78 |
79 | import javax.swing.JComponent;
80 |
81 |
82 | import javax.swing.JLabel;
83 |
84 | import javax.swing.JPanel;
85 |
86 | import javax.swing.JTextField;
87 |
88 | import javax.swing.Popup;
89 |
90 | import javax.swing.PopupFactory;
91 |
92 | import javax.swing.SwingUtilities;
93 |
94 | import javax.swing.event.AncestorEvent;
95 |
96 | import javax.swing.event.AncestorListener;
97 |
98 |
99 |
100 | /**
101 |
102 | * 日期选择器,可以指定日期的显示格式
103 |
104 | */
105 |
106 | public class DateChooser extends JPanel {
107 |
108 |
109 |
110 | private static final long serialVersionUID = 4529266044762990227L;
111 |
112 |
113 |
114 | private Date initDate;
115 |
116 | private Calendar now = Calendar.getInstance();
117 |
118 | private Calendar select;
119 |
120 | private JPanel monthPanel;//月历
121 |
122 | private JP1 jp1;//四块面板,组成
123 |
124 | private JP2 jp2;
125 |
126 | private JP3 jp3;
127 |
128 | private JP4 jp4;
129 |
130 | private Font font = new Font("宋体", Font.PLAIN, 12);
131 |
132 | private final LabelManager lm = new LabelManager();
133 |
134 | private SimpleDateFormat sdf;
135 |
136 | private boolean isShow = false;
137 |
138 | private Popup pop;
139 |
140 |
141 |
142 | private JComponent showDate;
143 |
144 |
145 |
146 | public static DateChooser getInstance() {
147 |
148 | return new DateChooser();
149 |
150 | }
151 |
152 |
153 |
154 | public static DateChooser getInstance(Date date) {
155 |
156 | return new DateChooser(date);
157 |
158 | }
159 |
160 |
161 |
162 | public static DateChooser getInstance(String format) {
163 |
164 | return new DateChooser(format);
165 |
166 | }
167 |
168 |
169 |
170 | public static DateChooser getInstance(Date date, String format) {
171 |
172 | return new DateChooser(date, format);
173 |
174 | }
175 |
176 |
177 |
178 | /**
179 |
180 | * Creates a new instance of DateChooser
181 |
182 | */
183 |
184 | private DateChooser() {
185 |
186 | this(new Date());
187 |
188 | }
189 |
190 |
191 |
192 | private DateChooser(Date date) {
193 |
194 | this(date, "yyyy年MM月dd日");
195 |
196 | }
197 |
198 |
199 |
200 | private DateChooser(String format) {
201 |
202 | this(new Date(), format);
203 |
204 | }
205 |
206 |
207 |
208 | private DateChooser(Date date, String format) {
209 |
210 | initDate = date;
211 |
212 | sdf = new SimpleDateFormat(format);
213 |
214 | select = Calendar.getInstance();
215 |
216 | select.setTime(initDate);
217 |
218 | initPanel();
219 |
220 | }
221 |
222 |
223 |
224 | /**
225 |
226 | * 是否允许用户选择
227 |
228 | */
229 |
230 | public void setEnabled(boolean b) {
231 |
232 | super.setEnabled(b);
233 |
234 | showDate.setEnabled(b);
235 |
236 | }
237 |
238 |
239 |
240 | /**
241 |
242 | *得到当前选择框的日期
243 |
244 | */
245 |
246 | public Date getDate() {
247 |
248 | return select.getTime();
249 |
250 | }
251 |
252 |
253 |
254 | public String getStrDate() {
255 |
256 | return sdf.format(select.getTime());
257 |
258 | }
259 |
260 |
261 |
262 | public String getStrDate(String format) {
263 |
264 | sdf = new SimpleDateFormat(format);
265 |
266 | return sdf.format(select.getTime());
267 |
268 | }
269 |
270 |
271 |
272 | //根据初始化的日期,初始化面板
273 |
274 | private void initPanel() {
275 |
276 | monthPanel = new JPanel(new BorderLayout());
277 |
278 | monthPanel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
279 |
280 | JPanel up = new JPanel(new BorderLayout());
281 |
282 | up.add(jp1 = new JP1(), BorderLayout.NORTH);
283 |
284 | up.add(jp2 = new JP2(), BorderLayout.CENTER);
285 |
286 | monthPanel.add(jp3 = new JP3(), BorderLayout.CENTER);
287 |
288 | monthPanel.add(up, BorderLayout.NORTH);
289 |
290 | monthPanel.add(jp4 = new JP4(), BorderLayout.SOUTH);
291 |
292 | this.addAncestorListener(new AncestorListener() {
293 |
294 | public void ancestorAdded(AncestorEvent event) {
295 |
296 |
297 |
298 | }
299 |
300 |
301 |
302 | public void ancestorRemoved(AncestorEvent event) {
303 |
304 |
305 |
306 | }
307 |
308 |
309 |
310 | //只要祖先组件一移动,马上就让popup消失
311 |
312 | public void ancestorMoved(AncestorEvent event) {
313 |
314 | hidePanel();
315 |
316 | }
317 |
318 | });
319 |
320 | }
321 |
322 |
323 |
324 | public void register(final JComponent showDate) {
325 |
326 | this.showDate = showDate;
327 |
328 |
329 |
330 | showDate.setRequestFocusEnabled(true);
331 |
332 | showDate.addMouseListener(new MouseAdapter() {
333 |
334 | public void mousePressed(MouseEvent me) {
335 |
336 | showDate.requestFocusInWindow();
337 |
338 | }
339 |
340 | });
341 |
342 | this.setBackground(Color.WHITE);
343 |
344 | this.add(showDate, BorderLayout.CENTER);
345 |
346 | this.setPreferredSize(new Dimension(90, 25));
347 |
348 | this.setBorder(BorderFactory.createLineBorder(Color.GRAY));
349 |
350 | showDate.addMouseListener(new MouseAdapter() {
351 |
352 | public void mouseEntered(MouseEvent me) {
353 |
354 | if (showDate.isEnabled()) {
355 |
356 | showDate.setCursor(new Cursor(Cursor.HAND_CURSOR));
357 |
358 | showDate.setForeground(Color.RED);
359 |
360 | }
361 |
362 | }
363 |
364 |
365 |
366 | public void mouseExited(MouseEvent me) {
367 |
368 | if (showDate.isEnabled()) {
369 |
370 | showDate.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
371 |
372 | showDate.setForeground(Color.BLACK);
373 |
374 | }
375 |
376 | }
377 |
378 |
379 |
380 | public void mousePressed(MouseEvent me) {
381 |
382 | if (showDate.isEnabled()) {
383 |
384 | showDate.setForeground(Color.CYAN);
385 |
386 | if (isShow) {
387 |
388 | hidePanel();
389 |
390 | } else {
391 |
392 | showPanel(showDate);
393 |
394 | }
395 |
396 | }
397 |
398 | }
399 |
400 |
401 |
402 | public void mouseReleased(MouseEvent me) {
403 |
404 | if (showDate.isEnabled()) {
405 |
406 | showDate.setForeground(Color.BLACK);
407 |
408 | }
409 |
410 | }
411 |
412 | });
413 |
414 | showDate.addFocusListener(new FocusListener() {
415 |
416 | public void focusLost(FocusEvent e) {
417 |
418 | hidePanel();
419 |
420 | }
421 |
422 |
423 |
424 | public void focusGained(FocusEvent e) {
425 |
426 |
427 |
428 | }
429 |
430 | });
431 |
432 | }
433 |
434 |
435 |
436 | //根据新的日期刷新
437 |
438 | private void refresh() {
439 |
440 | jp1.updateDate();
441 |
442 | jp2.updateDate();
443 |
444 | jp3.updateDate();
445 |
446 | jp4.updateDate();
447 |
448 | SwingUtilities.updateComponentTreeUI(this);
449 |
450 | }
451 |
452 |
453 |
454 | //提交日期
455 |
456 | private void commit() {
457 |
458 | if (showDate instanceof JTextField) {
459 |
460 | ((JTextField) showDate).setText(sdf.format(select.getTime()));
461 |
462 | }else if (showDate instanceof JLabel) {
463 |
464 | ((JLabel) showDate).setText(sdf.format(select.getTime()));
465 |
466 | }
467 |
468 |
469 |
470 | hidePanel();
471 |
472 | }
473 |
474 |
475 |
476 | //隐藏日期选择面板
477 |
478 | private void hidePanel() {
479 |
480 | if (pop != null) {
481 |
482 | isShow = false;
483 |
484 | pop.hide();
485 |
486 | pop = null;
487 |
488 | }
489 |
490 | }
491 |
492 |
493 |
494 | //显示日期选择面板
495 |
496 | private void showPanel(Component owner) {
497 |
498 | if (pop != null) {
499 |
500 | pop.hide();
501 |
502 | }
503 |
504 | Point show = new Point(0, showDate.getHeight());
505 |
506 | SwingUtilities.convertPointToScreen(show, showDate);
507 |
508 | Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
509 |
510 | int x = show.x;
511 |
512 | int y = show.y;
513 |
514 | if (x < 0) {
515 |
516 | x = 0;
517 |
518 | }
519 |
520 | if (x > size.width - 295) {
521 |
522 | x = size.width - 295;
523 |
524 | }
525 |
526 | if (y < size.height - 170) {
527 |
528 | } else {
529 |
530 | y -= 188;
531 |
532 | }
533 |
534 | pop = PopupFactory.getSharedInstance().getPopup(owner, monthPanel, x, y);
535 |
536 | pop.show();
537 |
538 | isShow = true;
539 |
540 | }
541 |
542 |
543 |
544 | /**
545 |
546 | * 最上面的面板用来显示月份的增减
547 |
548 | */
549 |
550 | private class JP1 extends JPanel {
551 |
552 | private static final long serialVersionUID = -5638853772805561174L;
553 |
554 | JLabel yearleft, yearright, monthleft, monthright, center, centercontainer;
555 |
556 |
557 |
558 | public JP1() {
559 |
560 | super(new BorderLayout());
561 |
562 | this.setBackground(new Color(160, 185, 215));
563 |
564 | initJP1();
565 |
566 | }
567 |
568 |
569 |
570 | private void initJP1() {
571 |
572 | yearleft = new JLabel(" <<", JLabel.CENTER);
573 |
574 | yearleft.setToolTipText("上一年");
575 |
576 | yearright = new JLabel(">> ", JLabel.CENTER);
577 |
578 | yearright.setToolTipText("下一年");
579 |
580 | yearleft.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
581 |
582 | yearright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
583 |
584 |
585 |
586 | monthleft = new JLabel(" <", JLabel.RIGHT);
587 |
588 | monthleft.setToolTipText("上一月");
589 |
590 | monthright = new JLabel("> ", JLabel.LEFT);
591 |
592 | monthright.setToolTipText("下一月");
593 |
594 | monthleft.setBorder(BorderFactory.createEmptyBorder(2, 30, 0, 0));
595 |
596 | monthright.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 30));
597 |
598 |
599 |
600 | centercontainer = new JLabel("", JLabel.CENTER);
601 |
602 | centercontainer.setLayout(new BorderLayout());
603 |
604 | center = new JLabel("", JLabel.CENTER);
605 |
606 |
607 |
608 | centercontainer.add(monthleft, BorderLayout.WEST);
609 |
610 | centercontainer.add(center, BorderLayout.CENTER);
611 |
612 | centercontainer.add(monthright, BorderLayout.EAST);
613 |
614 |
615 |
616 | this.add(yearleft, BorderLayout.WEST);
617 |
618 | this.add(centercontainer, BorderLayout.CENTER);
619 |
620 | this.add(yearright, BorderLayout.EAST);
621 |
622 | this.setPreferredSize(new Dimension(295, 25));
623 |
624 |
625 |
626 | updateDate();
627 |
628 |
629 |
630 | yearleft.addMouseListener(new MouseAdapter() {
631 |
632 | public void mouseEntered(MouseEvent me) {
633 |
634 | yearleft.setCursor(new Cursor(Cursor.HAND_CURSOR));
635 |
636 | yearleft.setForeground(Color.RED);
637 |
638 | }
639 |
640 |
641 |
642 | public void mouseExited(MouseEvent me) {
643 |
644 | yearleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
645 |
646 | yearleft.setForeground(Color.BLACK);
647 |
648 | }
649 |
650 |
651 |
652 | public void mousePressed(MouseEvent me) {
653 |
654 | select.add(Calendar.YEAR, -1);
655 |
656 | yearleft.setForeground(Color.WHITE);
657 |
658 | refresh();
659 |
660 | }
661 |
662 |
663 |
664 | public void mouseReleased(MouseEvent me) {
665 |
666 | yearleft.setForeground(Color.BLACK);
667 |
668 | }
669 |
670 | });
671 |
672 | yearright.addMouseListener(new MouseAdapter() {
673 |
674 | public void mouseEntered(MouseEvent me) {
675 |
676 | yearright.setCursor(new Cursor(Cursor.HAND_CURSOR));
677 |
678 | yearright.setForeground(Color.RED);
679 |
680 | }
681 |
682 |
683 |
684 | public void mouseExited(MouseEvent me) {
685 |
686 | yearright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
687 |
688 | yearright.setForeground(Color.BLACK);
689 |
690 | }
691 |
692 |
693 |
694 | public void mousePressed(MouseEvent me) {
695 |
696 | select.add(Calendar.YEAR, 1);
697 |
698 | yearright.setForeground(Color.WHITE);
699 |
700 | refresh();
701 |
702 | }
703 |
704 |
705 |
706 | public void mouseReleased(MouseEvent me) {
707 |
708 | yearright.setForeground(Color.BLACK);
709 |
710 | }
711 |
712 | });
713 |
714 | monthleft.addMouseListener(new MouseAdapter() {
715 |
716 | public void mouseEntered(MouseEvent me) {
717 |
718 | monthleft.setCursor(new Cursor(Cursor.HAND_CURSOR));
719 |
720 | monthleft.setForeground(Color.RED);
721 |
722 | }
723 |
724 |
725 |
726 | public void mouseExited(MouseEvent me) {
727 |
728 | monthleft.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
729 |
730 | monthleft.setForeground(Color.BLACK);
731 |
732 | }
733 |
734 |
735 |
736 | public void mousePressed(MouseEvent me) {
737 |
738 | select.add(Calendar.MONTH, -1);
739 |
740 | monthleft.setForeground(Color.WHITE);
741 |
742 | refresh();
743 |
744 | }
745 |
746 |
747 |
748 | public void mouseReleased(MouseEvent me) {
749 |
750 | monthleft.setForeground(Color.BLACK);
751 |
752 | }
753 |
754 | });
755 |
756 | monthright.addMouseListener(new MouseAdapter() {
757 |
758 | public void mouseEntered(MouseEvent me) {
759 |
760 | monthright.setCursor(new Cursor(Cursor.HAND_CURSOR));
761 |
762 | monthright.setForeground(Color.RED);
763 |
764 | }
765 |
766 |
767 |
768 | public void mouseExited(MouseEvent me) {
769 |
770 | monthright.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
771 |
772 | monthright.setForeground(Color.BLACK);
773 |
774 | }
775 |
776 |
777 |
778 | public void mousePressed(MouseEvent me) {
779 |
780 | select.add(Calendar.MONTH, 1);
781 |
782 | monthright.setForeground(Color.WHITE);
783 |
784 | refresh();
785 |
786 | }
787 |
788 |
789 |
790 | public void mouseReleased(MouseEvent me) {
791 |
792 | monthright.setForeground(Color.BLACK);
793 |
794 | }
795 |
796 | });
797 |
798 | }
799 |
800 |
801 |
802 | private void updateDate() {
803 |
804 | center.setText(select.get(Calendar.YEAR) + "年" + (select.get(Calendar.MONTH) + 1) + "月");
805 |
806 | }
807 |
808 | }
809 |
810 |
811 |
812 | private class JP2 extends JPanel {
813 |
814 | private static final long serialVersionUID = -8176264838786175724L;
815 |
816 |
817 |
818 | public JP2() {
819 |
820 | this.setPreferredSize(new Dimension(295, 20));
821 |
822 | }
823 |
824 |
825 |
826 | protected void paintComponent(Graphics g) {
827 |
828 | g.setFont(font);
829 |
830 | g.drawString("星期日 星期一 星期二 星期三 星期四 星期五 星期六", 5, 10);
831 |
832 | g.drawLine(0, 15, getWidth(), 15);
833 |
834 | }
835 |
836 |
837 |
838 | private void updateDate() {
839 |
840 |
841 |
842 | }
843 |
844 | }
845 |
846 |
847 |
848 | private class JP3 extends JPanel {
849 |
850 | private static final long serialVersionUID = 43157272447522985L;
851 |
852 |
853 |
854 | public JP3() {
855 |
856 | super(new GridLayout(6, 7));
857 |
858 | this.setPreferredSize(new Dimension(295, 100));
859 |
860 | initJP3();
861 |
862 | }
863 |
864 |
865 |
866 | private void initJP3() {
867 |
868 | updateDate();
869 |
870 | }
871 |
872 |
873 |
874 | public void updateDate() {
875 |
876 | this.removeAll();
877 |
878 | lm.clear();
879 |
880 | Date temp = select.getTime();
881 |
882 | Calendar select = Calendar.getInstance();
883 |
884 | select.setTime(temp);
885 |
886 | select.set(Calendar.DAY_OF_MONTH, 1);
887 |
888 | int index = select.get(Calendar.DAY_OF_WEEK);
889 |
890 | int sum = (index == 1 ? 8 : index);
891 |
892 | select.add(Calendar.DAY_OF_MONTH, 0 - sum);
893 |
894 | for (int i = 0; i < 42; i++) {
895 |
896 | select.add(Calendar.DAY_OF_MONTH, 1);
897 |
898 | lm.addLabel(new MyLabel(select.get(Calendar.YEAR), select.get(Calendar.MONTH), select.get(Calendar.DAY_OF_MONTH)));
899 |
900 | }
901 |
902 | for (MyLabel my : lm.getLabels()) {
903 |
904 | this.add(my);
905 |
906 | }
907 |
908 | select.setTime(temp);
909 |
910 | }
911 |
912 | }
913 |
914 |
915 |
916 | private class MyLabel extends JLabel implements Comparator, MouseListener, MouseMotionListener {
917 |
918 | private static final long serialVersionUID = 3668734399227577214L;
919 |
920 | private int year, month, day;
921 |
922 | private boolean isSelected;
923 |
924 |
925 |
926 | public MyLabel(int year, int month, int day) {
927 |
928 | super("" + day, JLabel.CENTER);
929 |
930 | this.year = year;
931 |
932 | this.day = day;
933 |
934 | this.month = month;
935 |
936 | this.addMouseListener(this);
937 |
938 | this.addMouseMotionListener(this);
939 |
940 | this.setFont(font);
941 |
942 | if (month == select.get(Calendar.MONTH)) {
943 |
944 | this.setForeground(Color.BLACK);
945 |
946 | } else {
947 |
948 | this.setForeground(Color.LIGHT_GRAY);
949 |
950 | }
951 |
952 | if (day == select.get(Calendar.DAY_OF_MONTH)) {
953 |
954 | this.setBackground(new Color(160, 185, 215));
955 |
956 | } else {
957 |
958 | this.setBackground(Color.WHITE);
959 |
960 | }
961 |
962 | }
963 |
964 |
965 |
966 | public boolean getIsSelected() {
967 |
968 | return isSelected;
969 |
970 | }
971 |
972 |
973 |
974 | public void setSelected(boolean b, boolean isDrag) {
975 |
976 | isSelected = b;
977 |
978 | if (b && !isDrag) {
979 |
980 | int temp = select.get(Calendar.MONTH);
981 |
982 | select.set(year, month, day);
983 |
984 | if (temp == month) {
985 |
986 | SwingUtilities.updateComponentTreeUI(jp3);
987 |
988 | } else {
989 |
990 | refresh();
991 |
992 | }
993 |
994 | }
995 |
996 | this.repaint();
997 |
998 | }
999 |
1000 |
1001 |
1002 | protected void paintComponent(Graphics g) {
1003 |
1004 | if (day == select.get(Calendar.DAY_OF_MONTH) && month == select.get(Calendar.MONTH)) {
1005 |
1006 | //如果当前日期是选择日期,则高亮显示
1007 |
1008 | g.setColor(new Color(160, 185, 215));
1009 |
1010 | g.fillRect(0, 0, getWidth(), getHeight());
1011 |
1012 | }
1013 |
1014 | if (year == now.get(Calendar.YEAR) && month == now.get(Calendar.MONTH) && day == now.get(Calendar.DAY_OF_MONTH)) {
1015 |
1016 | //如果日期和当前日期一样,则用红框
1017 |
1018 | Graphics2D gd = (Graphics2D) g;
1019 |
1020 | gd.setColor(Color.RED);
1021 |
1022 | Polygon p = new Polygon();
1023 |
1024 | p.addPoint(0, 0);
1025 |
1026 | p.addPoint(getWidth() - 1, 0);
1027 |
1028 | p.addPoint(getWidth() - 1, getHeight() - 1);
1029 |
1030 | p.addPoint(0, getHeight() - 1);
1031 |
1032 | gd.drawPolygon(p);
1033 |
1034 | }
1035 |
1036 | if (isSelected) {//如果被选中了就画出一个虚线框出来
1037 |
1038 | Stroke s = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 1.0f, new float[] { 2.0f, 2.0f }, 1.0f);
1039 |
1040 | Graphics2D gd = (Graphics2D) g;
1041 |
1042 | gd.setStroke(s);
1043 |
1044 | gd.setColor(Color.BLACK);
1045 |
1046 | Polygon p = new Polygon();
1047 |
1048 | p.addPoint(0, 0);
1049 |
1050 | p.addPoint(getWidth() - 1, 0);
1051 |
1052 | p.addPoint(getWidth() - 1, getHeight() - 1);
1053 |
1054 | p.addPoint(0, getHeight() - 1);
1055 |
1056 | gd.drawPolygon(p);
1057 |
1058 | }
1059 |
1060 | super.paintComponent(g);
1061 |
1062 | }
1063 |
1064 |
1065 |
1066 | public boolean contains(Point p) {
1067 |
1068 | return this.getBounds().contains(p);
1069 |
1070 | }
1071 |
1072 |
1073 |
1074 | private void update() {
1075 |
1076 | repaint();
1077 |
1078 | }
1079 |
1080 |
1081 |
1082 | public void mouseClicked(MouseEvent e) {
1083 |
1084 | }
1085 |
1086 |
1087 |
1088 | public void mousePressed(MouseEvent e) {
1089 |
1090 | isSelected = true;
1091 |
1092 | update();
1093 |
1094 | }
1095 |
1096 |
1097 |
1098 | public void mouseReleased(MouseEvent e) {
1099 |
1100 | Point p = SwingUtilities.convertPoint(this, e.getPoint(), jp3);
1101 |
1102 | lm.setSelect(p, false);
1103 |
1104 | commit();
1105 |
1106 | }
1107 |
1108 |
1109 |
1110 | public void mouseEntered(MouseEvent e) {
1111 |
1112 | }
1113 |
1114 |
1115 |
1116 | public void mouseExited(MouseEvent e) {
1117 |
1118 | }
1119 |
1120 |
1121 |
1122 | public void mouseDragged(MouseEvent e) {
1123 |
1124 | Point p = SwingUtilities.convertPoint(this, e.getPoint(), jp3);
1125 |
1126 | lm.setSelect(p, true);
1127 |
1128 | }
1129 |
1130 |
1131 |
1132 | public void mouseMoved(MouseEvent e) {
1133 |
1134 | }
1135 |
1136 |
1137 |
1138 | public int compare(MyLabel o1, MyLabel o2) {
1139 |
1140 | Calendar c1 = Calendar.getInstance();
1141 |
1142 | c1.set(o1.year, o2.month, o1.day);
1143 |
1144 | Calendar c2 = Calendar.getInstance();
1145 |
1146 | c2.set(o2.year, o2.month, o2.day);
1147 |
1148 | return c1.compareTo(c2);
1149 |
1150 | }
1151 |
1152 | }
1153 |
1154 |
1155 |
1156 | private class LabelManager {
1157 |
1158 | private List list;
1159 |
1160 |
1161 |
1162 | public LabelManager() {
1163 |
1164 | list = new ArrayList();
1165 |
1166 | }
1167 |
1168 |
1169 |
1170 | public List getLabels() {
1171 |
1172 | return list;
1173 |
1174 | }
1175 |
1176 |
1177 |
1178 | public void addLabel(MyLabel my) {
1179 |
1180 | list.add(my);
1181 |
1182 | }
1183 |
1184 |
1185 |
1186 | public void clear() {
1187 |
1188 | list.clear();
1189 |
1190 | }
1191 |
1192 |
1193 |
1194 | @SuppressWarnings("unused")
1195 |
1196 | public void setSelect(MyLabel my, boolean b) {
1197 |
1198 | for (MyLabel m : list) {
1199 |
1200 | if (m.equals(my)) {
1201 |
1202 | m.setSelected(true, b);
1203 |
1204 | } else {
1205 |
1206 | m.setSelected(false, b);
1207 |
1208 | }
1209 |
1210 | }
1211 |
1212 | }
1213 |
1214 |
1215 |
1216 | public void setSelect(Point p, boolean b) {
1217 |
1218 | //如果是拖动,则要优化一下,以提高效率
1219 |
1220 | if (b) {
1221 |
1222 | //表示是否能返回,不用比较完所有的标签,能返回的标志就是把上一个标签和
1223 |
1224 | //将要显示的标签找到了就可以了
1225 |
1226 | boolean findPrevious = false, findNext = false;
1227 |
1228 | for (MyLabel m : list) {
1229 |
1230 | if (m.contains(p)) {
1231 |
1232 | findNext = true;
1233 |
1234 | if (m.getIsSelected()) {
1235 |
1236 | findPrevious = true;
1237 |
1238 | } else {
1239 |
1240 | m.setSelected(true, b);
1241 |
1242 | }
1243 |
1244 | } else if (m.getIsSelected()) {
1245 |
1246 | findPrevious = true;
1247 |
1248 | m.setSelected(false, b);
1249 |
1250 | }
1251 |
1252 | if (findPrevious && findNext) {
1253 |
1254 | return;
1255 |
1256 | }
1257 |
1258 | }
1259 |
1260 | } else {
1261 |
1262 | MyLabel temp = null;
1263 |
1264 | for (MyLabel m : list) {
1265 |
1266 | if (m.contains(p)) {
1267 |
1268 | temp = m;
1269 |
1270 | } else if (m.getIsSelected()) {
1271 |
1272 | m.setSelected(false, b);
1273 |
1274 | }
1275 |
1276 | }
1277 |
1278 | if (temp != null) {
1279 |
1280 | temp.setSelected(true, b);
1281 |
1282 | }
1283 |
1284 | }
1285 |
1286 | }
1287 |
1288 |
1289 |
1290 | }
1291 |
1292 |
1293 |
1294 | private class JP4 extends JPanel {
1295 |
1296 | private static final long serialVersionUID = -6391305687575714469L;
1297 |
1298 |
1299 |
1300 | public JP4() {
1301 |
1302 | super(new BorderLayout());
1303 |
1304 | this.setPreferredSize(new Dimension(295, 20));
1305 |
1306 | this.setBackground(new Color(160, 185, 215));
1307 |
1308 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
1309 |
1310 | final JLabel jl = new JLabel("今天: " + sdf.format(new Date()));
1311 |
1312 | jl.setToolTipText("点击选择今天日期");
1313 |
1314 | this.add(jl, BorderLayout.CENTER);
1315 |
1316 | jl.addMouseListener(new MouseAdapter() {
1317 |
1318 | public void mouseEntered(MouseEvent me) {
1319 |
1320 | jl.setCursor(new Cursor(Cursor.HAND_CURSOR));
1321 |
1322 | jl.setForeground(Color.RED);
1323 |
1324 | }
1325 |
1326 |
1327 |
1328 | public void mouseExited(MouseEvent me) {
1329 |
1330 | jl.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
1331 |
1332 | jl.setForeground(Color.BLACK);
1333 |
1334 | }
1335 |
1336 |
1337 |
1338 | public void mousePressed(MouseEvent me) {
1339 |
1340 | jl.setForeground(Color.WHITE);
1341 |
1342 | select.setTime(new Date());
1343 |
1344 | refresh();
1345 |
1346 | commit();
1347 |
1348 | }
1349 |
1350 |
1351 |
1352 | public void mouseReleased(MouseEvent me) {
1353 |
1354 | jl.setForeground(Color.BLACK);
1355 |
1356 | }
1357 |
1358 | });
1359 |
1360 | }
1361 |
1362 |
1363 |
1364 | private void updateDate() {
1365 |
1366 |
1367 |
1368 | }
1369 |
1370 | }
1371 | }
--------------------------------------------------------------------------------
/weiboPicDownloader/src/main/java/weibo/FileUtils.java:
--------------------------------------------------------------------------------
1 | package weibo;
2 |
3 | import java.io.BufferedOutputStream;
4 | import java.io.File;
5 | import java.io.FileOutputStream;
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 | import java.net.HttpURLConnection;
9 | import java.net.URL;
10 |
11 | import org.apache.commons.io.IOUtils;
12 |
13 | public class FileUtils {
14 | /**
15 | * 最大图片大小40M
16 | * */
17 | private static final long MAX_DOWNLOAD_SIZE = 40L * 1024 * 1024;
18 |
19 | /**
20 | * UA
21 | * */
22 | static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36";
23 |
24 | public static void byte2File(byte[] buf, String path, String fileName) {
25 | BufferedOutputStream bos = null;
26 | FileOutputStream fos = null;
27 | File file = null;
28 | File pathF = new File(path);
29 | if (!pathF.exists()) {
30 | pathF.mkdirs();
31 | }
32 | try {
33 | file = new File(pathF, fileName);
34 | fos = new FileOutputStream(file);
35 | bos = new BufferedOutputStream(fos);
36 | bos.write(buf);
37 | } catch (Exception e) {
38 | e.printStackTrace();
39 | } finally {
40 | if (bos != null) {
41 | try {
42 | bos.close();
43 | } catch (IOException e) {
44 | e.printStackTrace();
45 | }
46 | }
47 | if (fos != null) {
48 | try {
49 | fos.close();
50 | } catch (IOException e) {
51 | e.printStackTrace();
52 | }
53 | }
54 | }
55 | }
56 | /**
57 | * 下载指定文件到内存
58 | *
59 | * @param webUrl
60 | * @return byte
61 | *
62 | *
63 | */
64 | public static byte[] download(String webUrl, int timeOut) {
65 | HttpURLConnection connection = null;
66 | long start = System.currentTimeMillis();
67 | try {
68 | URL url = new URL(webUrl);
69 | connection = (HttpURLConnection) url.openConnection();
70 | connection.setConnectTimeout(timeOut);
71 | connection.setReadTimeout(timeOut);
72 | connection.setRequestProperty("User-Agent", USER_AGENT);
73 | int len = connection.getContentLength();
74 | if (len >= MAX_DOWNLOAD_SIZE) {
75 | return null;
76 | }
77 | if (len == -1) {
78 | try (InputStream in = connection.getInputStream()) {
79 | return IOUtils.toByteArray(connection.getInputStream());
80 | }
81 | } else {
82 | byte[] data = new byte[len];
83 | byte[] buffer = new byte[4096 * 2];
84 | int count = 0, sum = 0;
85 | try (InputStream in = connection.getInputStream()) {
86 | while ((count = in.read(buffer)) > 0) {
87 | long elapse = System.currentTimeMillis() - start;
88 | if (elapse >= timeOut) {
89 | data = null;
90 | break;
91 | }
92 | System.arraycopy(buffer, 0, data, sum, count);
93 | sum += count;
94 | }
95 | }
96 | return data;
97 | }
98 | } catch (Exception e) {
99 | return null;
100 | } finally {
101 | if (connection != null) {
102 | connection.disconnect();
103 | }
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/weiboPicDownloader/src/main/java/weibo/ImageDownloadTask.java:
--------------------------------------------------------------------------------
1 | package weibo;
2 |
3 | import java.util.concurrent.CountDownLatch;
4 |
5 | public class ImageDownloadTask implements Runnable{
6 | private CountDownLatch downLatch;
7 | private int imageIndex;
8 | private String imageUrl;
9 |
10 | public int getImageIndex() {
11 | return imageIndex;
12 | }
13 | public void setImageIndex(int imageIndex) {
14 | this.imageIndex = imageIndex;
15 | }
16 | public String getImageUrl() {
17 | return imageUrl;
18 | }
19 | public void setImageUrl(String imageUrl) {
20 | this.imageUrl = imageUrl;
21 | }
22 |
23 | public ImageDownloadTask(CountDownLatch downLatch, int imageIndex, String imageUrl) {
24 | super();
25 | this.downLatch = downLatch;
26 | this.imageIndex = imageIndex;
27 | this.imageUrl = imageUrl;
28 | }
29 |
30 | @Override
31 | public void run() {
32 | try{
33 | System.out.println("下载图片: " + ( imageIndex + 1));
34 | byte[] imgBytes = FileUtils.download(imageUrl, 100_000);
35 | FileUtils.byte2File(imgBytes, WeiboDownloader.IMG_LOCATION, imageIndex+1+getSuffix(imageUrl));
36 | }catch (Exception e) {
37 | }finally {
38 | downLatch.countDown();
39 | }
40 | }
41 | private String getSuffix(String url){
42 | if(!url.substring(url.lastIndexOf("/")).contains(".")){
43 | return ".jpg";
44 | }
45 | try{
46 | return url.substring(url.lastIndexOf("."));
47 | }catch(Exception e){
48 | e.printStackTrace();
49 | }
50 | return ".jpg";
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/weiboPicDownloader/src/main/java/weibo/MainGui.java:
--------------------------------------------------------------------------------
1 | package weibo;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 | import java.awt.event.ActionEvent;
6 | import java.awt.event.ActionListener;
7 |
8 |
9 | public class MainGui extends JFrame {
10 | private static final long serialVersionUID = -8161981948004677531L;
11 | int DEFAULT_WIDTH = 300;
12 | int DEFAULT_HEIGHT = 200;
13 | private JLabel label;
14 | private JComboBox faceCombo;
15 | private static TextField tf;
16 | private static JButton filePathButton;
17 | private static DateChooser startTimeChooser;
18 | private static DateChooser endTimeChooser;
19 | private static JLabel endShowDate;
20 | private static JLabel startShowDate;
21 | private static Button button;
22 | private static String type;
23 | private static String name;
24 | private static String startTime ;
25 | private static String endTime;
26 | private static String filePath;
27 |
28 | public MainGui() {
29 | this.setTitle("微博图片下载");
30 | this.setSize(this.DEFAULT_WIDTH, this.DEFAULT_HEIGHT);
31 | this.setLayout(new GridLayout(6, 2,3,3));
32 | // 第一行内容
33 | label = new JLabel("账号类型:");
34 | label.setSize(200,10000);
35 |
36 | faceCombo = new JComboBox<>();
37 | faceCombo.setEditable(false);
38 | faceCombo.setEnabled(true);
39 | // faceCombo.addItem("用户昵称");
40 | // faceCombo.addItem("用户名");
41 | faceCombo.addItem("用户ID");
42 | this.add(label);
43 | this.add(faceCombo);
44 | label.setHorizontalAlignment(SwingConstants.RIGHT);
45 |
46 | // 第二行内容
47 | JLabel label2 = new JLabel("昵称");
48 | label2.setHorizontalAlignment(SwingConstants.RIGHT);
49 | tf = new TextField(20);
50 | this.add(label2);
51 | this.add(tf);
52 |
53 | // 第三行内容
54 | JLabel label3 = new JLabel("开始时间");
55 | label3.setHorizontalAlignment(SwingConstants.RIGHT);
56 | this.add(label3);
57 |
58 | startTimeChooser = DateChooser.getInstance("yyyy-MM-dd");
59 | startShowDate = new JLabel("单击选择日期");
60 | startTimeChooser.register(startShowDate);
61 | this.add(startShowDate);
62 |
63 | // 第四行内容
64 | JLabel label4 = new JLabel("结束时间");
65 | label4.setHorizontalAlignment(SwingConstants.RIGHT);
66 | this.add(label4);
67 |
68 | endTimeChooser = DateChooser.getInstance("yyyy-MM-dd");
69 | endShowDate = new JLabel("单击选择日期");
70 | endTimeChooser.register(endShowDate);
71 | this.add(endShowDate);
72 |
73 | button = new Button("Start");
74 | button.addActionListener(new ActionListener() {
75 | @Override
76 | public void actionPerformed(ActionEvent e) {
77 | type = (String)faceCombo.getSelectedItem();
78 | name = tf.getText();
79 | System.out.println(startShowDate.getText());
80 | System.out.println(endShowDate.getText());
81 | if (startShowDate.getText() != "单击选择日期") {
82 | startTime = startTimeChooser.getStrDate();
83 | }
84 | if (endShowDate.getText() != "单击选择日期") {
85 | endTime = endTimeChooser.getStrDate();
86 | }
87 | if ((startTime == null && endTime != null) || (startTime != null && endTime == null)) {
88 | JOptionPane.showMessageDialog(null, "输入完整的起止时间或不输入时间","错误", JOptionPane.ERROR_MESSAGE);
89 | return;
90 | } else {
91 | if (startTime != null && endTime != null) {
92 | WeiboUtils.needFilterDate = true;
93 | WeiboUtils.startTime = startTime;
94 | WeiboUtils.endTime = endTime;
95 | }
96 | }
97 | filePath = filePathButton.getText();
98 | if (type == null || "".equals(type) || name == null || "".equals(name)
99 | || filePath == null || "".equals(filePath) || "选择".equals(filePath)) {
100 | JOptionPane.showMessageDialog(null, "请输入正确的名称,以及图片保存地址","错误", JOptionPane.ERROR_MESSAGE);
101 | return;
102 | }
103 | System.out.println("type is " + type);
104 | System.out.println("name is " + name);
105 | System.out.println("startTime is " + startTime);
106 | System.out.println("end is " + endTime);
107 | System.out.println("filePath is " + filePath);
108 | Thread th = new Thread(new Runnable() {
109 | @Override
110 | public void run() {
111 | try{
112 | button.setEnabled(false);
113 | WeiboDownloader.downloadCli(type, name, filePath, startTime, endTime);
114 | } catch (Exception err) {
115 | button.setEnabled(true);
116 | System.out.println("出错了。 详细错误信息: ");
117 | err.printStackTrace();
118 | } finally {
119 | button.setEnabled(true);
120 | WeiboUtils.needFilterDate = false;
121 | WeiboUtils.startTime = null;
122 | WeiboUtils.endTime = null;
123 | }
124 | }
125 | });
126 | th.start();
127 | }
128 | });
129 | // 第五行内容
130 | JLabel label5 = new JLabel("文件保存地址");
131 | label5.setHorizontalAlignment(SwingConstants.RIGHT);
132 | this.add(label5);
133 | filePathButton = new JButton("选择");
134 | filePathButton.addActionListener(new ActionListener() {
135 | @Override
136 | public void actionPerformed(ActionEvent e) {
137 | JFileChooser jfc=new JFileChooser();
138 | jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY );
139 | jfc.showDialog(new JLabel(), "选择");
140 | if (jfc.getSelectedFile() != null) {
141 | filePathButton.setText(jfc.getSelectedFile().getAbsolutePath());
142 | }
143 | }
144 | });
145 | this.add(filePathButton);
146 | this.add(button);
147 |
148 | }
149 | public static void main(String[] args){
150 | MainGui mainGui = new MainGui();
151 | mainGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
152 | mainGui.setLocationRelativeTo(null);
153 | mainGui.setVisible(true);
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/weiboPicDownloader/src/main/java/weibo/WeiboDownloader.java:
--------------------------------------------------------------------------------
1 | package weibo;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.util.HashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 | import java.util.concurrent.CountDownLatch;
9 | import java.util.concurrent.ExecutorService;
10 | import java.util.concurrent.Executors;
11 |
12 | import org.apache.http.ParseException;
13 |
14 | public class WeiboDownloader {
15 | public static final int TYPE_USER_ID = 1;
16 | public static final int TYPE_USER_NAME = 2;
17 | public static final int TYPE_USER_NICKNAME = 3;
18 |
19 | /**
20 | * UA
21 | * */
22 | static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36";
23 |
24 | /**
25 | * 路径
26 | * */
27 | public static String IMG_LOCATION = "E:\\img\\";
28 |
29 | public static void downloadCli(String selectType, String inputName, String filePath, String startTime, String endTime) throws ParseException, IOException, InterruptedException {
30 | IMG_LOCATION = filePath;
31 | Map map = new HashMap<>();
32 | // 目前失效 先注释
33 | // map.put("用户昵称", TYPE_USER_NICKNAME);
34 | // map.put("用户名", TYPE_USER_NAME);
35 | map.put("用户ID", TYPE_USER_ID);
36 | int type = map.get(selectType);
37 | String containerId = "";
38 | if(type == TYPE_USER_ID){
39 | String uid = inputName;
40 | containerId = WeiboUtils.uidToContainerId(uid);
41 | }else if(type == TYPE_USER_NAME){
42 | String name = inputName;
43 | containerId = WeiboUtils.usernameToContainerId(name);
44 | }else if(type == TYPE_USER_NICKNAME){
45 | String nickname = inputName;
46 | containerId = WeiboUtils.nicknameToContainerId(nickname);
47 | }
48 | if (containerId == null) {
49 | System.out.println("未找到用户, 请检查账户名");
50 | return;
51 | }
52 | List imgUrls;
53 | try {
54 | imgUrls = WeiboUtils.getAllImgURL(containerId);
55 | } catch (Exception e1) {
56 | e1.printStackTrace();
57 | System.out.println("解析出现异常, 请稍候再试!");
58 | return;
59 | }
60 | System.out.println("分析完毕");
61 | System.out.println("图片数量: " + imgUrls.size());
62 |
63 | if(!IMG_LOCATION.endsWith("/")&&!IMG_LOCATION.endsWith("\\")){
64 | if(IMG_LOCATION.contains("/"))
65 | IMG_LOCATION = IMG_LOCATION + "/" + containerId.substring(6) + "/";
66 | else
67 | IMG_LOCATION = IMG_LOCATION + "\\" + containerId.substring(6) + "\\";
68 | }
69 |
70 | if(!new File(IMG_LOCATION).exists()){
71 | try{
72 | new File(IMG_LOCATION).mkdirs();
73 | System.out.println("创建 " + IMG_LOCATION + "成功");
74 | }catch (Exception e) {
75 | System.out.println("无法创建目录,请手动创建");
76 | }
77 | }
78 | CountDownLatch downLatch = new CountDownLatch(imgUrls.size());
79 | ExecutorService executor = Executors.newFixedThreadPool(4);
80 | for(int i=0;i getAllImgURL(String containerid) throws Exception {
89 | List urls = new ArrayList();
90 | int i = 1;
91 | while (getImgURL(containerid, i, urls) > 0) {
92 | System.out.println("分析微博中: " + i);
93 | i++;
94 | // 防封,分析一次页面休息+1S
95 | Thread.sleep(1000);
96 | }
97 | return urls;
98 | }
99 |
100 | private static int getImgURL(String containerid, int page, List urls) throws ParseException, IOException {
101 | String url = "https://m.weibo.cn/api/container/getIndex?count=25&page=" + page + "&containerid=" + containerid;
102 | System.out.println(url);
103 | HttpClient httpClient = getHttpClient();
104 | HttpGet get = new HttpGet(url);
105 | get.setHeader("User-Agent", USER_AGENT);
106 | HttpResponse response = httpClient.execute(get);
107 | String ret = EntityUtils.toString(response.getEntity(), "utf-8");
108 | JsonObject root;
109 | try {
110 | // 防封
111 | root = new JsonParser().parse(ret).getAsJsonObject();
112 | } catch (Exception e) {
113 | try {
114 | Thread.sleep(60000);
115 | } catch (Exception e1) {
116 |
117 | }
118 | return 1;
119 | }
120 | JsonObject asJsonObject = root.getAsJsonObject("data");
121 | JsonArray array = asJsonObject.getAsJsonArray("cards");
122 | for (int i = 0; i < array.size(); i++) {
123 | JsonObject mblog = array.get(i).getAsJsonObject().getAsJsonObject("mblog");
124 | if (mblog != null) {
125 | if (WeiboUtils.needFilterDate) {
126 | String createAt = mblog.get("created_at").getAsString();
127 | String date = WeiboUtils.getDate(createAt);
128 | if (date.compareTo(WeiboUtils.startTime) < 0 || date.compareTo(WeiboUtils.endTime) > 0){
129 | continue;
130 | }
131 | }
132 | JsonArray pics = mblog.getAsJsonArray("pics");
133 | if (pics != null) {
134 | for (int j = 0; j < pics.size(); j++) {
135 | JsonObject o = pics.get(j).getAsJsonObject();
136 | JsonObject large = o.getAsJsonObject("large");
137 | if (large != null) {
138 | urls.add(large.get("url").getAsString());
139 | }
140 | }
141 | }
142 | }
143 | }
144 | return array.size();
145 | }
146 |
147 | /**
148 | * 初始HttpClient
149 | *
150 | * @author yanximin
151 | */
152 | public static HttpClient getHttpClient() {
153 | DefaultHttpClient httpClient = new DefaultHttpClient();
154 | httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 30000);
155 | httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 30000);
156 | return httpClient;
157 | }
158 |
159 | public static long transWeiboDateStrToTimeStamp(String weiboDateStr) {
160 | if (weiboDateStr == null || "".equals(weiboDateStr)) {
161 | return 0;
162 | }
163 | if (weiboDateStr.contains("秒前")) {
164 | weiboDateStr = weiboDateStr.replace("秒前", "");
165 | int second = Integer.valueOf(weiboDateStr);
166 | return System.currentTimeMillis() - second * 1000;
167 | }
168 | if (weiboDateStr.contains("分钟前")) {
169 | weiboDateStr = weiboDateStr.replace("分钟前", "");
170 | int second = Integer.valueOf(weiboDateStr);
171 | return System.currentTimeMillis() - second * 1000 * 60;
172 | }
173 | if (weiboDateStr.contains("小时前")) {
174 | weiboDateStr = weiboDateStr.replace("小时前", "");
175 | int second = Integer.valueOf(weiboDateStr);
176 | return System.currentTimeMillis() - second * 1000 * 3600;
177 | }
178 | if (weiboDateStr.contains("昨天")) {
179 | Date yesterdayTimestamp = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24);
180 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
181 | String yesterday = simpleDateFormat.format(yesterdayTimestamp);
182 | weiboDateStr = weiboDateStr.replace("昨天", yesterday);
183 | SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMdd HH:mm");
184 | try {
185 | Date date = sDateFormat.parse(weiboDateStr);
186 | return date.getTime();
187 | } catch (Exception e) {
188 | return 0;
189 | }
190 | }
191 | if (weiboDateStr.contains("-")) {
192 | if (!weiboDateStr.startsWith("20")) {
193 | int year = new Date().getYear() + 1900;
194 | weiboDateStr = year + "-" + weiboDateStr;
195 | }
196 | SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd");
197 | try {
198 | Date date = sDateFormat.parse(weiboDateStr);
199 | return date.getTime();
200 | } catch (Exception e) {
201 | return 0;
202 | }
203 | }
204 | return 0;
205 | }
206 | public static String getDate(String weiboDateStr) {
207 | long time;
208 | try {
209 | time = WeiboUtils.transWeiboDateStrToTimeStamp(weiboDateStr);
210 | } catch (Exception e) {
211 | time = 0;
212 | }
213 |
214 | SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd");
215 | return sDateFormat.format(new Date(time));
216 | }
217 | }
218 |
--------------------------------------------------------------------------------