<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>润物无声 &#187; Baidu</title>
	<atom:link href="http://blog.zhourunsheng.com/tag/baidu/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.zhourunsheng.com</link>
	<description>天空一朵雨做的云</description>
	<lastBuildDate>Sat, 08 May 2021 05:17:21 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.41</generator>
	<item>
		<title>关于Java程序自动发布文章到百度空间的程序更新</title>
		<link>http://blog.zhourunsheng.com/2012/02/%e5%85%b3%e4%ba%8ejava%e7%a8%8b%e5%ba%8f%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4%e7%9a%84%e7%a8%8b%e5%ba%8f%e6%9b%b4%e6%96%b0/</link>
		<comments>http://blog.zhourunsheng.com/2012/02/%e5%85%b3%e4%ba%8ejava%e7%a8%8b%e5%ba%8f%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4%e7%9a%84%e7%a8%8b%e5%ba%8f%e6%9b%b4%e6%96%b0/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 05:21:09 +0000</pubDate>
		<dc:creator><![CDATA[润物无声]]></dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[Baidu]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.zhourunsheng.com/?p=1313</guid>
		<description><![CDATA[<p>利用Java程序自动发送博客文章到百度空间，可以参照我的博文《Java程序自动发布文章到百度空间》，通过修改程 [&#8230;]</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2012/02/%e5%85%b3%e4%ba%8ejava%e7%a8%8b%e5%ba%8f%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4%e7%9a%84%e7%a8%8b%e5%ba%8f%e6%9b%b4%e6%96%b0/">关于Java程序自动发布文章到百度空间的程序更新</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>利用Java程序自动发送博客文章到百度空间，可以参照我的博文《<a href="http://blog.zhourunsheng.com/2011/07/java%E7%A8%8B%E5%BA%8F%E8%87%AA%E5%8A%A8%E5%8F%91%E5%B8%83%E6%96%87%E7%AB%A0%E5%88%B0%E7%99%BE%E5%BA%A6%E7%A9%BA%E9%97%B4/">Java程序自动发布文章到百度空间</a>》，通过修改程序的源码，主要是登录账户的信息就可以进行代码测试。</p>
<p>2012年开始，百度空间的博文发布系统进行了一些调整，主要是变更了一些请求的API参数和URL地址，以及增加跨域检测，提高了安全性，所以旧的代码无法正常工作，更新过的可以正常工作的代码在本文的最后有下载链接。</p>
<p><strong>主要变更点如下：</strong></p>
<ol>
<li>百度空间的登录
<p>params.put("mem_pass", "on");</p>
</li>
<li>添加博文类别
<p>params.put("spIsBlogCatAdd", "1");</p>
</li>
<li>博文发布
<p>参数变更：params.put("previewImg", "");</p>
<p>提交地址变更：private static final String SUBMIT_CREATBLOG_URL = "http://hi.baidu.com/" + Config.USERNAME + "/blog/submit/createblog";</p>
</li>
<li>跨域检测
<p>httpPost.setRequestHeader("Referer", refURL);</p>
</li>
</ol>
<p><strong>代码下载</strong></p>
<p>程序源码 <a href="http://carey-blog-image.googlecode.com/files/BaiduCreateBlog%2820120205%29.zip">BaiduCreateBlog(20120205)</a></p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2012/02/%e5%85%b3%e4%ba%8ejava%e7%a8%8b%e5%ba%8f%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4%e7%9a%84%e7%a8%8b%e5%ba%8f%e6%9b%b4%e6%96%b0/">关于Java程序自动发布文章到百度空间的程序更新</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zhourunsheng.com/2012/02/%e5%85%b3%e4%ba%8ejava%e7%a8%8b%e5%ba%8f%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4%e7%9a%84%e7%a8%8b%e5%ba%8f%e6%9b%b4%e6%96%b0/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>同步wordpress文章到百度空间</title>
		<link>http://blog.zhourunsheng.com/2011/07/%e5%90%8c%e6%ad%a5wordpress%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/</link>
		<comments>http://blog.zhourunsheng.com/2011/07/%e5%90%8c%e6%ad%a5wordpress%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/#comments</comments>
		<pubDate>Sat, 02 Jul 2011 09:49:27 +0000</pubDate>
		<dc:creator><![CDATA[润物无声]]></dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[Baidu]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://blog.zhourunsheng.com/?p=282</guid>
		<description><![CDATA[<p>本文实现了wordpress的插件开发，自动同步 wordpress 的文章到百度空间。 == Descrip [&#8230;]</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2011/07/%e5%90%8c%e6%ad%a5wordpress%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/">同步wordpress文章到百度空间</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>本文实现了wordpress的插件开发，自动同步 wordpress 的文章到百度空间。</p>
<p><strong>== Description ==</strong></p>
<p>同步发布 WordPress 博文到 百度空间.</p>
<p><del datetime="2013-05-19T05:51:18+00:00">1. 支持设置发布到百度空间中文章的评论权限。</del><br />
2. 支持设置发布到百度空间中文章的访问权限。<br />
<del datetime="2013-05-19T05:51:18+00:00">3. 支持设置发布到百度空间中文章的转载权限。</del><br />
4. 支持将Wordpress中文章链接发布到百度空间。<br />
5. 支持发布到百度空间中文章的自动归类</p>
<p><span id="more-282"></span></p>
<p><strong>== Installation ==</strong></p>
<p>1. 上传 整个文件夹 wp2baiduzone 到 `/wp-content/plugins/` 目录<br />
2. 后台控制面板"插件(Plugins)"中激活 wp2baiduzone 插件<br />
3. 后台控制面板"配置(Settings)-&gt;wp2baiduzone"中配置插件信息（百度空间的账户信息和博文同步的权限信息）</p>
<p>软件配置界面：</p>
<p><a href="http://blog.zhourunsheng.com/wp-content/uploads/2011/07/wordpress-baidu.jpg"><img class="alignnone size-full wp-image-283" title="wordpress-baidu" alt="" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/07/wordpress-baidu.jpg" width="500" height="327" /></a></p>
<p>下载地址：<a href="http://wordpress.org/extend/plugins/wp2baiduzone/">http://wordpress.org/extend/plugins/wp2baiduzone/</a></p>
<h3>变更历史</h3>
<p>时间：2012-06-26</p>
<p>鉴于最近百度空间进行了升级，所以原有的插件在新环境下可能无法正常工作，为了不影响新旧空间所有用户的使用，插件暂时没有做更新，对新版的百度空间做了一款补充插件，和原有插件的文件名都相同，下载下来替换掉现有的插件即可，部分功能有变更，待后续完善，下载地址 <a href="http://carey-blog-image.googlecode.com/files/wp2baiduzone%2820120626%29.zip">wp2baiduzone(20120626).zip</a>.</p>
<p>时间：2013-09-19</p>
<p>新版的百度空间已经稳定了，插件目前更新到1.3稳定版本，可以进行同步。</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2011/07/%e5%90%8c%e6%ad%a5wordpress%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/">同步wordpress文章到百度空间</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zhourunsheng.com/2011/07/%e5%90%8c%e6%ad%a5wordpress%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>通过GAE平台自动发布文章到百度空间</title>
		<link>http://blog.zhourunsheng.com/2011/07/%e9%80%9a%e8%bf%87gae%e5%b9%b3%e5%8f%b0%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/</link>
		<comments>http://blog.zhourunsheng.com/2011/07/%e9%80%9a%e8%bf%87gae%e5%b9%b3%e5%8f%b0%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/#comments</comments>
		<pubDate>Sat, 02 Jul 2011 09:37:47 +0000</pubDate>
		<dc:creator><![CDATA[润物无声]]></dc:creator>
				<category><![CDATA[云计算]]></category>
		<category><![CDATA[Baidu]]></category>
		<category><![CDATA[GAE]]></category>

		<guid isPermaLink="false">http://blog.zhourunsheng.com/?p=278</guid>
		<description><![CDATA[<p>昨天写了一篇通过Java程序自动发送文章到百度空间，具体实现原理和代码请参照&#60;&#60;Java程序自动发 [&#8230;]</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2011/07/%e9%80%9a%e8%bf%87gae%e5%b9%b3%e5%8f%b0%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/">通过GAE平台自动发布文章到百度空间</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>昨天写了一篇通过Java程序自动发送文章到百度空间，具体实现原理和代码请参照&lt;&lt;<a href="http://carey.sinaapp.com/?p=271">Java程序自动发布文章到百度空间</a>&gt;&gt;</p>
<p>今天把那版代码进行了更新，现在可以放置到GAE平台了，这样基于GAE平台环境搭建的个人博客就可以</p>
<p>很方便的将个人的博文同步到百度空间。</p>
<p>具体的实现原理现在不多说了，现在展示一下核心代码：</p>
<p><strong>1.</strong> Config.Java</p>
<p>配置个人百度空间的账户名和密码</p>
<pre>package com.carey.baidublog;  

public class Config {    
 public static final String USERNAME = "username";    
 public static final String PASSWORD = "password";
}</pre>
<p><span id="more-278"></span></p>
<p><strong>2. </strong>GAEPublishBaiduActicleServlet.java</p>
<p>用来处理GAE的servlet请求</p>
<pre>package com.carey.gae.baidu;  
import java.io.IOException;
import javax.servlet.http.*;  
import com.carey.baidublog.BDHttpClient;  

public class GAEPublishBaiduActicleServlet extends HttpServlet {    
 private static final long serialVersionUID = 1L;      

 public void doGet(HttpServletRequest req, HttpServletResponse resp)  throws IOException {        
  try {         
   BDHttpClient.publishBlog("gae-title", "gae-content", "gae-category");        
  } catch (Exception e) {            
   e.printStackTrace();        
  }          

  resp.setContentType("text/plain");        
  resp.getWriter().println("成功发布一篇博文到百度空间");    
 }
}</pre>
<p><strong>3. </strong>BDHttpClient.java</p>
<p>完成百度博文的发布</p>
<pre>package com.carey.baidublog;  
import java.net.URL;
import java.util.HashMap;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;  
import javax.servlet.http.HttpServletResponse;  
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPMethod;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;  

public class BDHttpClient {    
 private static final String LOGIN_URL = "&lt;a href="https://passport.baidu.com/?login"&gt;https://passport.baidu.com/?login&lt;/a&gt;";    
 private static final String CREATBLOG_URL = "&lt;a href="http://hi.baidu.com/"&gt;http://hi.baidu.com/&lt;/a&gt;" + Config.USERNAME + "/creat/blog";    
 private static final String MODIFYCATEGORY_URL = "&lt;a href="http://hi.baidu.com/"&gt;http://hi.baidu.com/&lt;/a&gt;" + Config.USERNAME + "/modify/category/0";    
 private static final String COMMITBLOG_URL = "&lt;a href="http://hi.baidu.com/"&gt;http://hi.baidu.com/&lt;/a&gt;" + Config.USERNAME + "/commit";      
 private static final URLFetchService urlFetchService = URLFetchServiceFactory.getURLFetchService();    
 private static final HashMap globalCookies = new HashMap();      

 public static void publishBlog(String title, String content, String category) throws Exception {        
  // step 1, login baidu and get cookies        
  String cookies = LoginBaidu();          

  // step 2, get Bdstoken        
  String bdstoken = getBdstoken(cookies);          

  // step 3, publish article        
  if (bdstoken != null) {            
   postBlog(cookies, bdstoken, title, content, category);        
  } else {            
   throw new Exception("bdstoken == null");        
  }    
 }      

 private static String LoginBaidu() {        
  HashMap params = new HashMap();        
  params.put("username", Config.USERNAME);        
  params.put("password", Config.PASSWORD);        
  params.put("pwd", "1");         

  try {            
   httpPost(null, LOGIN_URL, generateQueryString(params));        
  } catch (Exception e) {        
   e.printStackTrace();        
  }         

  return globalCookies.get("set-cookie");    
 }    

 private static String getBdstoken(String cookies) {     
  try {            
   String res = httpGet(cookies, CREATBLOG_URL, null);       
   Pattern p = Pattern.compile("bdstoken=([0-9a-z]+)\W");        
   Matcher m = p.matcher(res);           

   if (m.find()) {                
    return m.group(1);            
   }      
  } catch (Exception e) {          
   e.printStackTrace();    
  }        

  return null;   
 }    

 private static String createCategory(String cookies, String bdstoken, String category) throws Exception {       
  HashMap params = new HashMap();          

  // bdstoken        
  params.put("bdstoken", bdstoken);          

  // create category        
  params.put("ct", "2");        
  params.put("cm", "1");          

  // Article category, such as "Android", "Google", "默认分类"        
  params.put("spBlogCatName", category);        
  params.put("spRefURL", MODIFYCATEGORY_URL);          

  return httpPost(cookies, COMMITBLOG_URL, generateQueryString(params));    
 }      

 private static String postBlog(String cookies, String bdstoken, String title, String content, String category) throws Exception {  
  HashMap params = new HashMap();          

  // bdstoken        
  params.put("bdstoken", bdstoken);          

  // new blog        
  params.put("ct", "1");        
  params.put("cm", "1");          

  // add a new article        
  params.put("spBlogID", "");        
  params.put("edithid", "");        
  params.put("spBlogCatName_o", "");          

  // Article title        
  params.put("spBlogTitle", title);          

  // Article content        
  params.put("spBlogText", content);          

  // Article category, such as "Android", "Google", "默认分类"        
  params.put("spBlogCatName", category);          

  // Article view Permissions,        
  // 0 --&gt; every one 1 --&gt; only friend 3 --&gt; only oneself       
  params.put("spBlogPower", "0");         

  // 0: forbidden comment 1: allow comment       
  params.put("spIsCmtAllow", "1");         

  // 0: allow share 1: forbidden share       
  params.put("spShareNotAllow", "0");         

  // verify code       
  params.put("spVcode", "");    
  params.put("spVerifyKey", "");         

  // first create category      
  createCategory(cookies, bdstoken, category);        

  return httpPost(cookies, COMMITBLOG_URL, generateQueryString(params));    
 }      

 private static String generateQueryString(HashMap params) {     
  StringBuffer sb = new StringBuffer();         
  if (params != null &amp;&amp; !params.isEmpty()) {          
   Set keys = params.keySet();            
   for (String key : keys) {            
    sb.append(key);               
    sb.append("=");               
    sb.append(params.get(key));       
    sb.append("&amp;");        
   }              

   // remove last &amp;           
   sb.deleteCharAt(sb.length() - 1);          
  }       

  return sb.toString();   
 }      

 private static String httpGet(String cookies, String url, String queryString) throws Exception {     
  String ret = null;         
  if (queryString != null &amp;&amp; !queryString.equals("")) {  
   url += "?" + queryString;        
  }          

  final HTTPRequest request = new HTTPRequest(new URL(url));        
  if (cookies != null) {           
   request.setHeader(new HTTPHeader("Cookie", cookies));       
  }

  try {            
   final HTTPResponse response = urlFetchService.fetch(request);          
   if (HttpServletResponse.SC_OK != response.getResponseCode()) {      
    System.err.println("HttpGet Method failed: " + response.getResponseCode());           
   }    

   ret = new String(response.getContent(), "UTF-8");       
  } catch (Exception e) {            
   throw new Exception(e);        
  }          

  return ret;    
 }     

 private static String httpPost(String cookies, String url, String queryString) throws Exception {        
  String ret = null;          
  final HTTPRequest request = new HTTPRequest(new URL(url), HTTPMethod.POST);        
  request.setHeader(new HTTPHeader("Content-Type", "application/x-www-form-urlencoded"));        

  if (cookies != null) {            
   request.setHeader(new HTTPHeader("Cookie", cookies));        
  }          

  if (queryString != null &amp;&amp; !queryString.equals("")) {            
   request.setPayload(queryString.getBytes("UTF-8"));        
  }          

  try {           
   final HTTPResponse response = urlFetchService.fetch(request);           
   if (HttpServletResponse.SC_OK != response.getResponseCode()) {                
    System.err.println("HttpPost Method failed: "  + response.getResponseCode());            
   }             

   // Get site cookie            
   for (HTTPHeader header : response.getHeaders()) {                
    if (header.getName().equalsIgnoreCase("set-cookie")) {                   
     globalCookies.put("set-cookie", header.getValue());                
    }     
   }     

   ret = new String(response.getContent(), "UTF-8");        
  } catch (Exception e) {         
   throw new Exception(e);   
  }         

  return ret;    
 }
}</pre>
<p>以上程序在GAE环境测试通过，运行过程序后会自动在百度空间发布一篇文章，截图如下：</p>
<p><a href="http://blog.zhourunsheng.com/wp-content/uploads/2011/07/gae-baidu.jpg"><img class="alignnone size-full wp-image-279" title="gae-baidu" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/07/gae-baidu.jpg" alt="" width="500" height="270" /></a></p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2011/07/%e9%80%9a%e8%bf%87gae%e5%b9%b3%e5%8f%b0%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/">通过GAE平台自动发布文章到百度空间</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zhourunsheng.com/2011/07/%e9%80%9a%e8%bf%87gae%e5%b9%b3%e5%8f%b0%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java程序自动发布文章到百度空间</title>
		<link>http://blog.zhourunsheng.com/2011/07/java%e7%a8%8b%e5%ba%8f%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/</link>
		<comments>http://blog.zhourunsheng.com/2011/07/java%e7%a8%8b%e5%ba%8f%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/#comments</comments>
		<pubDate>Sat, 02 Jul 2011 09:20:20 +0000</pubDate>
		<dc:creator><![CDATA[润物无声]]></dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[Baidu]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.zhourunsheng.com/?p=271</guid>
		<description><![CDATA[<p>这几天建立了个博客，想把这个博客的内容同时导入到其他博客中去，同时，当在本博客发表一篇博文的时候，也同步传输到 [&#8230;]</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2011/07/java%e7%a8%8b%e5%ba%8f%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/">Java程序自动发布文章到百度空间</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></description>
				<content:encoded><![CDATA[<p>这几天建立了个博客，想把这个博客的内容同时导入到其他博客中去，同时，当在本博客发表一篇博文的时候，也同步传输到其他博客中去，</p>
<p>这样就方便多了，以后只要维护一个就ok了。</p>
<p>CSDN的博客开放的比较好，符合<a href="http://www.xmlrpc.com/metaWeblogApi">http://www.xmlrpc.com/metaWeblogApi</a>标准，可以有开放的API来调用，容易解决。</p>
<p>目前遇到的问题就是导入博文到百度空间，貌似百度现在还没有做出什么开放的API来，没办法来直接调用，不过也有方法来解决，</p>
<p>那就是通过程序来模拟浏览器的登录过程和发表文章的过程，通过测试，搞定。。O(∩_∩)O哈哈~</p>
<p>下面介绍一下程序的思路和展示一下源码：</p>
<p><strong>1. </strong>基本思路就是通过程序来模拟浏览器的登录过程，本文的代码基于Java语言实现，主要利用的就是Apache的HttpClient包。</p>
<p><strong>2. </strong>大家首先可以利用浏览器的插件来捕获我们正常到百度登录过程，和发表博文过程的所有Http请求的数据，着重分析一下</p>
<p>表单数据的提交，就可以知道百度空间发文在后台做了那些操作和需要哪些重要的数据来验证用户的正常登录。</p>
<p><strong>3. </strong>用程序来模拟浏览器登录的最重要的处理，就是Cookie的保存和后续数据的传输，因为像百度这类需要用户输入账户</p>
<p>和密码来登录的系统，并且具有密码记忆功能的网站，用户的验证信息都存储在Cookie中。</p>
<p><strong>4. </strong>因为为了让百度服务器识别用户的登录，那就要在程序中记录第一次登录过程的Cookie数据，然后在以后的http请求中</p>
<p>将cookie数据回传给服务器，那样服务器就认为你一直登录了，不然文章是不能正确发布出去的，因为你没有cookie的话，</p>
<p>服务器还认为你没有登录过，会拒绝操作。</p>
<p><strong>5. </strong>用户的身份验证解决了以后，百度发表文章的时候，还要多加一步验证，就是通过访问新建博文的页面，获取一个临时的百度</p>
<p>token，它会与你接下来发表的博文一一对应，我猜测可能是服务器支持单用户多点登录，同时发表多篇博文吧，不过这都没</p>
<p>关系了，反正我们照做就行啦。</p>
<p><strong>6. </strong>文章分类的处理，我发现百度这边做的不够智能，如果你发表博文的时候，指定了一个不存在的类别，直接决绝发布，所以，还是</p>
<p>想个笨点的办法，每次发布博文前，先建立一个类别，如果已经有了这个类型，重新建立一次也没关系，反正也不会覆盖掉，因为百度</p>
<p>会拒绝建立新的类别，错误类型是类别已存在，这个善意的错误忽略就ok。。。哈哈</p>
<p><strong>7. </strong>所有这些前期工作做好了，就能正常发布文章了，下面贴出一下源码文件，大家按照自己的方式去修改吧：</p>
<p>1. Config.java</p>
<p>主要配置一下个人百度账号的用户名和密码</p>
<pre>package com.carey.baidublog;   
 public class Config {    
 public static final String USERNAME = "username";    
 public static final String PASSWORD = "password";
}</pre>
<p>2. PublishBlog.java</p>
<p>测试程序，调用函数发布文章到百度空间</p>
<pre>package com.carey.baidublog;  
public class PublistBlog {    
 public static void main(String[] args) {        
  try {            
   BDHttpClient.publishBlog("Article-Title", "Article-Content",  "Article-category");            
   System.out.println("成功发布一篇文章到百度空间");        
  } catch (Exception e) {            
      e.printStackTrace();        
  }    
 }
}</pre>
<p>3. BDHttpClient.java</p>
<p>发布百度博文的实现类，主要是http请求和cookie的处理，以及获取百度令牌token</p>
<pre>package com.carey.baidublog;
  
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;  
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;  

public class BDHttpClient {    
    private static final String LOGIN_URL = "&lt;a href="https://passport.baidu.com/?login"&gt;https://passport.baidu.com/?login&lt;/a&gt;";    
 private static final String CREATBLOG_URL = "&lt;a href="http://hi.baidu.com/"&gt;http://hi.baidu.com/&lt;/a&gt;" + Config.USERNAME + "/creat/blog";    
 private static final String MODIFYCATEGORY_URL = "&lt;a href="http://hi.baidu.com/"&gt;http://hi.baidu.com/&lt;/a&gt;" + Config.USERNAME + "/modify/category/0";    
 private static final String COMMITBLOG_URL = "&lt;a href="http://hi.baidu.com/"&gt;http://hi.baidu.com/&lt;/a&gt;" + Config.USERNAME + "/commit";      
 private static final int CONNECTION_TIMEOUT = 20000;      
 
 public static void publishBlog(String title, String content, String category) throws Exception {        
  // step 1, login baidu and get cookies        
  Cookie[] cookies = LoginBaidu();          
 
  // step 2, get Bdstoken        
  String bdstoken = getBdstoken(cookies);          
 
  // step 3, publish article        
  if (bdstoken != null) {            
  postBlog(cookies, bdstoken, title, content, category);        
  } else { 
  throw new Exception("bdstoken == null");        
  }    
 }      
 
 private static HttpClient getHttpClient(Cookie[] cookies) {        
  HttpClient httpClient = new HttpClient();          
  if (cookies != null) {            
   // add cookies            
   httpClient.getState().addCookies(cookies);            
   // httpClient.getParams().setParameter("http.protocol.cookie-policy",            
   // CookiePolicy.BROWSER_COMPATIBILITY);        
   }          
   return httpClient;    
  }      
  
 private static Cookie[] LoginBaidu() {        
  HttpClient httpClient = getHttpClient(null);          
  HashMap params = new HashMap();        
  params.put("username", Config.USERNAME);        
  params.put("password", Config.PASSWORD);        
  params.put("pwd", "1");          
  
  try {            
   httpPost(httpClient, LOGIN_URL, generateQueryString(params));        
  } catch (Exception e) {            
   e.printStackTrace();        
  }          
  
  return httpClient.getState().getCookies();    
 }      
 
 private static String getBdstoken(Cookie[] cookies) {        
  HttpClient httpClient = getHttpClient(cookies);          
  try {            
   String res = httpGet(httpClient, CREATBLOG_URL, null);            
   Pattern p = Pattern.compile("bdstoken=([0-9a-z]+)\W");            
   Matcher m = p.matcher(res);            
   
   if (m.find()) {                
    return m.group(1);            
   }        
  } catch (Exception e) {            
   e.printStackTrace();        
  }          
  
  return null;    
 }      
 
 private static String createCategory(Cookie[] cookies, String bdstoken, String category) throws Exception {        
  HttpClient httpClient = getHttpClient(cookies);          
  HashMap params = new HashMap();          
  // bdstoken        
  params.put("bdstoken", bdstoken);          
  
  // create category        
  params.put("ct", "2");        
  params.put("cm", "1");          
  
  // Article category, such as "Android", "Google", "默认分类"       
  params.put("spBlogCatName", category);        
  params.put("spRefURL", MODIFYCATEGORY_URL);          
  return httpPost(httpClient, COMMITBLOG_URL, generateQueryString(params));    
 }      
 
 private static String postBlog(Cookie[] cookies, String bdstoken, String title, String content, String category) throws Exception { 
  HttpClient httpClient = getHttpClient(cookies);          
  HashMap params = new HashMap();          
  
  // bdstoken        
  params.put("bdstoken", bdstoken);          
  
  // new blog        
  params.put("ct", "1");        
  params.put("cm", "1");          
  
  // add a new article        
  params.put("spBlogID", "");        
  params.put("edithid", "");        
  params.put("spBlogCatName_o", "");          
  
  // Article title        
  params.put("spBlogTitle", title);          
  
  // Article content        
  params.put("spBlogText", content);          
  
  // Article category, such as "Android", "Google", "默认分类"       
  params.put("spBlogCatName", category);          
  
  // Article view Permissions,        
  // 0 --&gt; every one 1 --&gt; only friend 3 --&gt; only oneself        
  params.put("spBlogPower", "0");          
  
  // 0: forbidden comment 1: allow comment        
  params.put("spIsCmtAllow", "1");          
  
  // 0: allow share 1: forbidden share        
  params.put("spShareNotAllow", "0");          
  
  // verify code        
  params.put("spVcode", "");        
  params.put("spVerifyKey", "");          
  
  // first create category        
  createCategory(cookies, bdstoken, category);          
  return httpPost(httpClient, COMMITBLOG_URL, generateQueryString(params));    
 }      
 
 private static String generateQueryString(HashMap params) {        
  StringBuffer sb = new StringBuffer();          
  if (params != null &amp;&amp; !params.isEmpty()) {            
   Set keys = params.keySet();              
   for (String key : keys) {                
    sb.append(key);                
    sb.append("=");                
    sb.append(params.get(key));                
    sb.append("&amp;");            
   }              
   // remove last &amp;            
   sb.deleteCharAt(sb.length() - 1);        
  }          
  
  return sb.toString();    
 }      
 
 private static String httpGet(HttpClient httpClient, String url, String queryString) throws Exception {       
  String responseData = null;          
  if (queryString != null &amp;&amp; !queryString.equals("")) {    
   url += "?" + queryString;        
  }          
  
  GetMethod httpGet = new GetMethod(url);        
  httpGet.getParams().setParameter("http.socket.timeout", new Integer(CONNECTION_TIMEOUT));          
  
  try {            
   int statusCode = httpClient.executeMethod(httpGet);            
   if (statusCode != HttpStatus.SC_OK) {              
    System.err.println("HttpGet Method failed: " + httpGet.getStatusLine());            
   }            
   
   responseData = getResponseBodyAsString(httpGet);        
  } catch (Exception e) {            
   throw new Exception(e);        
  } finally {            
   httpGet.releaseConnection();       
  }    
  
  return responseData;    
 }      
 
 private static String httpPost(HttpClient httpClient, String url, String queryString) throws Exception {   
  String responseData = null;
  PostMethod httpPost = new PostMethod(url); 
  httpPost.addParameter("Content-Type", "application/x-www-form-urlencoded");
        httpPost.getParams().setParameter("http.socket.timeout", new Integer(CONNECTION_TIMEOUT));         
  if (queryString != null &amp;&amp; !queryString.equals("")) {            
   httpPost.setRequestEntity(new ByteArrayRequestEntity(queryString.getBytes()));        
  }          
  
  try {            
   int statusCode = httpClient.executeMethod(httpPost);            
   if (statusCode != HttpStatus.SC_OK) {                
    System.err.println("HttpPost Method failed: " + httpPost.getStatusLine());            
   }            
   
   responseData = getResponseBodyAsString(httpPost);        
  } catch (Exception e) {            
   throw new Exception(e);        
  } finally {            
   httpPost.releaseConnection();        
  }          
  
  return responseData;    
 }      
 
 private static String getResponseBodyAsString(HttpMethod httpMethod) {        
  StringBuffer sb = new StringBuffer();          
  try {            
   BufferedReader br = new BufferedReader(new InputStreamReader( httpMethod.getResponseBodyAsStream()));            
   String line = br.readLine();            
   while (line != null) {                
    sb.append(line + "n");                
    line = br.readLine();            
   }        
  } catch (IOException e) {            
   e.printStackTrace();        
  }          
  
  return sb.toString();    
 }
}</pre>
<p>程序运行后会在百度空间发布一篇博文的，截图如下：</p>
<p><a href="http://blog.zhourunsheng.com/wp-content/uploads/2011/07/java-baidu.jpg"><img class="alignnone size-full wp-image-272" title="java-baidu" src="http://blog.zhourunsheng.com/wp-content/uploads/2011/07/java-baidu.jpg" alt="" width="500" height="218" /></a></p>
<p>有兴趣的童鞋希望给改进更好的版本，给我反馈一下，哈哈，就当人人为我，我为人人，做个小广告！</p>
<p>好了，到现在为止，工作都做完了，收工喽！！！</p>
<p><a rel="nofollow" href="http://blog.zhourunsheng.com/2011/07/java%e7%a8%8b%e5%ba%8f%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/">Java程序自动发布文章到百度空间</a>，首发于<a rel="nofollow" href="http://blog.zhourunsheng.com">润物无声</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.zhourunsheng.com/2011/07/java%e7%a8%8b%e5%ba%8f%e8%87%aa%e5%8a%a8%e5%8f%91%e5%b8%83%e6%96%87%e7%ab%a0%e5%88%b0%e7%99%be%e5%ba%a6%e7%a9%ba%e9%97%b4/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
