introduce HttpOptions for constructor; fix theVerge parsing
This commit is contained in:
@@ -282,6 +282,27 @@ namespace ReadSharp.Ports.NReadability
|
||||
.Where(e => tagName.Equals(e.Name.LocalName, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public static IEnumerable<XElement> GetElementsByClass(this XContainer container, string className)
|
||||
{
|
||||
if (container == null)
|
||||
{
|
||||
throw new ArgumentNullException("container");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(className))
|
||||
{
|
||||
throw new ArgumentNullException("className");
|
||||
}
|
||||
|
||||
if (className.StartsWith("."))
|
||||
{
|
||||
className = className.Remove(0, 1);
|
||||
}
|
||||
|
||||
return container.Descendants()
|
||||
.Where(e => e != null && e.GetAttributeValue("class", "").Contains(className)); //tagName.Equals(e.Name.LocalName, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public static IEnumerable<XElement> GetChildrenByTagName(this XContainer container, string tagName)
|
||||
{
|
||||
if (container == null)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -102,7 +103,7 @@ namespace ReadSharp.Ports.NReadability
|
||||
|
||||
private static readonly Regex _UnlikelyCandidatesRegex = new Regex("combx|comment|community|disqus|extra|foot|header|menu|remark|rss|shoutbox|sidebar|side|sponsor|ad-break|agegate|pagination|pager|popup|tweet|twitter", RegexOptions.IgnoreCase);
|
||||
private static readonly Regex _OkMaybeItsACandidateRegex = new Regex("and|article|body|column|main|shadow", RegexOptions.IgnoreCase);
|
||||
private static readonly Regex _PositiveWeightRegex = new Regex("article|body|content|entry|hentry|main|page|pagination|post|text|blog|story", RegexOptions.IgnoreCase);
|
||||
private static readonly Regex _PositiveWeightRegex = new Regex("article|body|content|entry|hentry|main|page|pagination|post|text|blog|story|paragraph|instapaper_body|entry-content|article-body|entry-body", RegexOptions.IgnoreCase);
|
||||
private static readonly Regex _NegativeWeightRegex = new Regex("combx|comment|com-|contact|foot|footer|footnote|masthead|media|meta|outbrain|promo|related|scroll|shoutbox|sidebar|side|sponsor|shopping|tags|tool|widget", RegexOptions.IgnoreCase);
|
||||
private static readonly Regex _NegativeLinkParentRegex = new Regex("(stories|articles|news|documents|posts|notes|series|historie|artykuly|artykuły|wpisy|dokumenty|serie|geschichten|erzählungen|erzahlungen)", RegexOptions.IgnoreCase);
|
||||
private static readonly Regex _Extraneous = new Regex("print|archive|comment|discuss|e[-]?mail|share|reply|all|login|sign|single|also", RegexOptions.IgnoreCase);
|
||||
@@ -123,7 +124,7 @@ namespace ReadSharp.Ports.NReadability
|
||||
private static readonly Regex _NextStoryLink = new Regex("(story|article|news|document|post|note|series|historia|artykul|artykuł|wpis|dokument|seria|geschichte|erzählung|erzahlung|artikel|serie)", RegexOptions.IgnoreCase);
|
||||
private static readonly Regex _PrevLink = new Regex("(prev|earl|[^b]old|new|wstecz|poprzednia|<|�)", RegexOptions.IgnoreCase);
|
||||
private static readonly Regex _PageRegex = new Regex("pag(e|ing|inat)|([^a-z]|^)pag([^a-z]|$)", RegexOptions.IgnoreCase);
|
||||
private static readonly Regex _LikelyParagraphDivRegex = new Regex("text|para|parbase", RegexOptions.IgnoreCase);
|
||||
private static readonly Regex _LikelyParagraphDivRegex = new Regex("text|para|parbase|paragraph", RegexOptions.IgnoreCase);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -135,7 +136,7 @@ namespace ReadSharp.Ports.NReadability
|
||||
private static readonly Dictionary<Regex, string> _articleContentElementHints =
|
||||
new Dictionary<Regex, string>
|
||||
{
|
||||
{ new Regex("^https?://(www|mobile)\\.theverge.com", RegexOptions.IgnoreCase), "article" },
|
||||
{ new Regex("^https?://(www|mobile)\\.theverge.com", RegexOptions.IgnoreCase), ".entry-body" },
|
||||
};
|
||||
|
||||
#endregion
|
||||
@@ -1141,6 +1142,8 @@ namespace ReadSharp.Ports.NReadability
|
||||
topCandidateElement.Add(documentBody.Nodes());
|
||||
}
|
||||
|
||||
Debug.WriteLine(topCandidateElement);
|
||||
|
||||
return topCandidateElement;
|
||||
}
|
||||
|
||||
@@ -1791,9 +1794,18 @@ namespace ReadSharp.Ports.NReadability
|
||||
throw new ArgumentException("Argument can't be null nor empty.", "articleContentElementHint");
|
||||
}
|
||||
|
||||
return document
|
||||
.GetElementsByTagName(articleContentElementHint)
|
||||
.FirstOrDefault();
|
||||
if (articleContentElementHint.StartsWith("."))
|
||||
{
|
||||
return document
|
||||
.GetElementsByClass(articleContentElementHint)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
return document
|
||||
.GetElementsByTagName(articleContentElementHint)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetArticleContentElementHint(string url)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
@@ -136,5 +137,14 @@ namespace ReadSharp.Tests
|
||||
//Article result = await reader.Read(new Uri("http://bit.ly/KAh7FJ"));
|
||||
//Assert.NotEmpty(result.Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TestVergeReturnsFullArticle()
|
||||
{
|
||||
Article result = await reader.Read(new Uri("http://www.theverge.com/2013/11/18/5116360/nokia-lumia-1520-review"));
|
||||
Debug.WriteLine(result.Content.Length);
|
||||
Assert.Contains("Three years ago, Nokia shipped over 110 million smartphones worldwide. ", result.Content);
|
||||
Assert.True(result.Content.Length > 6000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System.Net.Http;
|
||||
|
||||
namespace ReadSharp
|
||||
{
|
||||
public class HttpOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the custom HTTP handler.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The custom HTTP handler.
|
||||
/// </value>
|
||||
public HttpMessageHandler CustomHttpHandler { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the request timeout.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The timeout after which the requests cancels.
|
||||
/// </value>
|
||||
public int? RequestTimeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [use mobile user agent].
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [use mobile user agent]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool UseMobileUserAgent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used UserAgent for HTTP request
|
||||
/// </summary>
|
||||
public string UserAgent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used mobile UserAgent for HTTP request
|
||||
/// </summary>
|
||||
public string UserAgentMobile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates the default HTTP options.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static HttpOptions CreateDefault()
|
||||
{
|
||||
return new HttpOptions()
|
||||
{
|
||||
UserAgentMobile = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0; ARM; Mobile; Touch{0}) like Gecko",
|
||||
UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64{0}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1736.2 Safari/537.36 OPR/20.0.1380.1",
|
||||
UseMobileUserAgent = false,
|
||||
RequestTimeout = null,
|
||||
CustomHttpHandler = null
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,7 @@
|
||||
<Compile Include="IReader.cs" />
|
||||
<Compile Include="Models\Article.cs" />
|
||||
<Compile Include="Models\ArticleImage.cs" />
|
||||
<Compile Include="Models\HttpOptions.cs" />
|
||||
<Compile Include="Models\ReadOptions.cs" />
|
||||
<Compile Include="Reader.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
||||
+15
-19
@@ -19,11 +19,6 @@ namespace ReadSharp
|
||||
/// </summary>
|
||||
public class Reader : IReader
|
||||
{
|
||||
/// <summary>
|
||||
/// Used UserAgent for HTTP request
|
||||
/// </summary>
|
||||
protected string _userAgent = "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0; ARM; Mobile; Touch{0}) like Gecko";
|
||||
|
||||
/// <summary>
|
||||
/// REST client used for HTML retrieval
|
||||
/// </summary>
|
||||
@@ -44,10 +39,8 @@ namespace ReadSharp
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Reader" /> class.
|
||||
/// </summary>
|
||||
/// <param name="userAgent">Custom UserAgent string.</param>
|
||||
/// <param name="handler">The HttpMessage handler.</param>
|
||||
/// <param name="timeout">Request timeout (in seconds).</param>
|
||||
public Reader(string userAgent = null, HttpMessageHandler handler = null, int? timeout = null)
|
||||
/// <param name="options">The HTTP options.</param>
|
||||
public Reader(HttpOptions options = null)
|
||||
{
|
||||
// initialize transcoder
|
||||
_transcoder = new NReadabilityTranscoder(
|
||||
@@ -59,25 +52,25 @@ namespace ReadSharp
|
||||
readingSize: ReadingSize.Medium
|
||||
);
|
||||
|
||||
// get default HTTP options if none available
|
||||
if (options == null)
|
||||
{
|
||||
options = HttpOptions.CreateDefault();
|
||||
}
|
||||
|
||||
// initialize custom encoder
|
||||
_encoder = new Encodings.Encoder(true);
|
||||
|
||||
// override user agent
|
||||
if (!string.IsNullOrEmpty(userAgent))
|
||||
{
|
||||
_userAgent = userAgent;
|
||||
}
|
||||
|
||||
// initialize HTTP client
|
||||
_httpClient = new HttpClient(handler ?? new HttpClientHandler()
|
||||
_httpClient = new HttpClient(options.CustomHttpHandler ?? new HttpClientHandler()
|
||||
{
|
||||
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
|
||||
AllowAutoRedirect = true
|
||||
});
|
||||
|
||||
if (timeout.HasValue)
|
||||
if (options.RequestTimeout.HasValue)
|
||||
{
|
||||
_httpClient.Timeout = TimeSpan.FromSeconds(timeout.Value);
|
||||
_httpClient.Timeout = TimeSpan.FromSeconds(options.RequestTimeout.Value);
|
||||
}
|
||||
|
||||
// add accept types
|
||||
@@ -87,8 +80,11 @@ namespace ReadSharp
|
||||
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip,deflate");
|
||||
|
||||
// add user agent
|
||||
string userAgent = options.UseMobileUserAgent ? options.UserAgentMobile : options.UserAgent;
|
||||
|
||||
string version = Assembly.GetExecutingAssembly().FullName.Split(',')[1].Split('=')[1];
|
||||
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", String.Format(_userAgent, "; ReadSharp/" + version));
|
||||
|
||||
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", String.Format(userAgent, "; ReadSharp/" + version));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user