Selenium&EmguCV爬虫類画像認識を実現
9389 ワード
概要
爬虫類はウェブサイトの価格をつかむ必要があり、一般的なウェブページをつかむのとは異なり、コンテンツをつかむのはAJAXでロードされ、価格はCSSの背景画像で表示されます.
各数字には'p_などのスタイルが対応しています.h57_5'
数字に対応するスタイルと対応するbackgroundimgは動的に変化し、各住宅型の住宅価格を得る必要がある.その後、他のルートで住宅価格を取得しましたが、ここではSelenium&Emguで捕まえる方法を記録します.プロセス:
インプリメンテーション
```C#static void Main(string[] args) {
```
画像認識方法``C#
static Program() { ocr.SetVariable("tesseditchar_whitelist", "0123456789"); }
```
Seleniumはスクリーンショットの方法を内蔵して、ブラウザの中で表示する内容を切り取ることしかできなくて、1つの全スクリーンショットの方式を探し当てます(スクリーンショット+制御スクロールバーを内蔵して、ピクチャーのつなぎ合わせ)``C
public static Bitmap GetEntereScreenshot(IWebDriver _driver) {
```
最後に、転送された要素とフルスクリーンショットに基づいて、価格要素の画像を取得します.
```C#
public static Image SnapshotV2(this IWebElement element, Bitmap bitmap) { Size size = new Size( Math.Min(element.Size.Width, bitmap.Width), Math.Min(element.Size.Height, bitmap.Height)); Rectangle crop = new Rectangle(element.Location, size); return bitmap.Clone(crop, bitmap.PixelFormat); }
```
運転効果は以下の通り
爬虫類はウェブサイトの価格をつかむ必要があり、一般的なウェブページをつかむのとは異なり、コンテンツをつかむのはAJAXでロードされ、価格はCSSの背景画像で表示されます.
各数字には'p_などのスタイルが対応しています.h57_5'
.p_h57_5 {
background: url('http://pic.c-ctrip.com/priceblur/h57/3713de5c594648529f39d031243966dd.gif') no-repeat -590px;
padding: 0 6px;
font-size: 18px;
}
数字に対応するスタイルと対応するbackgroundimgは動的に変化し、各住宅型の住宅価格を得る必要がある.その後、他のルートで住宅価格を取得しましたが、ここではSelenium&Emguで捕まえる方法を記録します.プロセス:
1.Selenium
2.
3.Selenium
4.Selenium DOM , , , Emgu
インプリメンテーション
```C#static void Main(string[] args) {
//
ChromeOptions options = new ChromeOptions();
options.AddArguments("--start-maximized --disable-popup-blocking");
var driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("http://hotels.ctrip.com/hotel/992765.html");
try
{
new WebDriverWait(driver, TimeSpan.FromSeconds(1)).Until(
ExpectedConditions.ElementExists((By.ClassName("htl_room_table")))); //
}
finally
{
}
// ¥
ReadOnlyCollection<IWebElement> elementsList = driver.FindElementsByCssSelector("tr[expand]");
driver.ExecuteScript(@"
var arr = document.getElementsByTagName('dfn');
for(var i=0;i<arr.length;i++){
arr[i].style.display = 'none';
}
");
//
var image2 = GetEntereScreenshot(driver);
image2.Save(@"Z:\111.jpg");
//
Console.WriteLine("{0,-20}{1,-20}{2,-20}", " ", " ", " ");
foreach (IWebElement _ in elementsList)
{
//var image = _.Snapshot();
//image.Save(@"Z:\" + Guid.NewGuid() + ".jpg");
//var str = ORC_((Bitmap)image);
var roomType = "";
try
{
roomType = _.FindElement(By.CssSelector(".room_unfold")).Text;
}
catch (Exception)
{
}
var roomTypeText = regRoomType.Match(roomType);
var roomTypeName = _.FindElement(By.CssSelector("span.room_type_name")).Text;
//
var image = _.FindElement(By.CssSelector("span.base_price")).SnapshotV2(image2);
//
var price = ORC_((Bitmap)image);
Console.WriteLine("{0,-20}{1,-20}{2,-20}", roomTypeText.Value, roomTypeName, price);
}
Console.Read();
}
```
画像認識方法``C#
static Program() { ocr.SetVariable("tesseditchar_whitelist", "0123456789"); }
private static Tesseract _ocr = new Tesseract(@"C:\Emgu\emgucv-windows-universal-cuda 2.9.0.1922\bin\tessdata", "eng", Tesseract.OcrEngineMode.OEM_TESSERACT_CUBE_COMBINED);
//
public static string ORC_(Bitmap img)
{
//"" OCR
string re = "";
if (img == null)
return re;
else
{
Bgr drawColor = new Bgr(Color.Blue);
try
{
Image<Bgr, Byte> image = new Image<Bgr, byte>(img);
using (Image<Gray, byte> gray = image.Convert<Gray, Byte>())
{
_ocr.Recognize(gray);
Tesseract.Charactor[] charactors = _ocr.GetCharactors();
foreach (Tesseract.Charactor c in charactors)
{
image.Draw(c.Region, drawColor, 1);
}
re = _ocr.GetText();
}
return re;
}
catch (Exception ex)
{
return re;
}
}
}
```
Seleniumはスクリーンショットの方法を内蔵して、ブラウザの中で表示する内容を切り取ることしかできなくて、1つの全スクリーンショットの方式を探し当てます(スクリーンショット+制御スクロールバーを内蔵して、ピクチャーのつなぎ合わせ)``C
public static Bitmap GetEntereScreenshot(IWebDriver _driver) {
Bitmap stitchedImage = null;
try
{
long totalwidth1 = (long)((IJavaScriptExecutor)_driver).ExecuteScript("return document.body.offsetWidth");//documentElement.scrollWidth");
long totalHeight1 = (long)((IJavaScriptExecutor)_driver).ExecuteScript("return document.body.parentNode.scrollHeight");
int totalWidth = (int)totalwidth1;
int totalHeight = (int)totalHeight1;
// Get the Size of the Viewport
long viewportWidth1 = (long)((IJavaScriptExecutor)_driver).ExecuteScript("return document.body.clientWidth");//documentElement.scrollWidth");
long viewportHeight1 = (long)((IJavaScriptExecutor)_driver).ExecuteScript("return window.innerHeight");//documentElement.scrollWidth");
int viewportWidth = (int)viewportWidth1;
int viewportHeight = (int)viewportHeight1;
// Split the Screen in multiple Rectangles
List<Rectangle> rectangles = new List<Rectangle>();
// Loop until the Total Height is reached
for (int i = 0; i < totalHeight; i += viewportHeight)
{
int newHeight = viewportHeight;
// Fix if the Height of the Element is too big
if (i + viewportHeight > totalHeight)
{
newHeight = totalHeight - i;
}
// Loop until the Total Width is reached
for (int ii = 0; ii < totalWidth; ii += viewportWidth)
{
int newWidth = viewportWidth;
// Fix if the Width of the Element is too big
if (ii + viewportWidth > totalWidth)
{
newWidth = totalWidth - ii;
}
// Create and add the Rectangle
Rectangle currRect = new Rectangle(ii, i, newWidth, newHeight);
rectangles.Add(currRect);
}
}
// Build the Image
stitchedImage = new Bitmap(totalWidth, totalHeight);
// Get all Screenshots and stitch them together
Rectangle previous = Rectangle.Empty;
foreach (var rectangle in rectangles)
{
// Calculate the Scrolling (if needed)
if (previous != Rectangle.Empty)
{
int xDiff = rectangle.Right - previous.Right;
int yDiff = rectangle.Bottom - previous.Bottom;
// Scroll
//selenium.RunScript(String.Format("window.scrollBy({0}, {1})", xDiff, yDiff));
((IJavaScriptExecutor)_driver).ExecuteScript(String.Format("window.scrollBy({0}, {1})", xDiff, yDiff));
System.Threading.Thread.Sleep(200);
}
// Take Screenshot
var screenshot = ((ITakesScreenshot)_driver).GetScreenshot();
// Build an Image out of the Screenshot
Image screenshotImage;
using (MemoryStream memStream = new MemoryStream(screenshot.AsByteArray))
{
screenshotImage = Image.FromStream(memStream);
}
// Calculate the Source Rectangle
Rectangle sourceRectangle = new Rectangle(viewportWidth - rectangle.Width, viewportHeight - rectangle.Height, rectangle.Width, rectangle.Height);
// Copy the Image
using (Graphics g = Graphics.FromImage(stitchedImage))
{
g.DrawImage(screenshotImage, rectangle, sourceRectangle, GraphicsUnit.Pixel);
}
// Set the Previous Rectangle
previous = rectangle;
}
}
catch (Exception ex)
{
// handle
}
return stitchedImage;
}
```
最後に、転送された要素とフルスクリーンショットに基づいて、価格要素の画像を取得します.
```C#
public static Image SnapshotV2(this IWebElement element, Bitmap bitmap) { Size size = new Size( Math.Min(element.Size.Width, bitmap.Width), Math.Min(element.Size.Height, bitmap.Height)); Rectangle crop = new Rectangle(element.Location, size); return bitmap.Clone(crop, bitmap.PixelFormat); }
```
運転効果は以下の通り