# Changelog of G2 Scraper — Software Reviews, Ratings, Emails & Leads (`pro100chok/g2-scraper`) Actor

- **URL**: https://apify.com/pro100chok/g2-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/pro100chok/g2-scraper.md

## Changelog

### 1.3.10 (2026-09-19) — a fresh cookie jar stopped being accepted

- **Every page came back as a challenge, with a jar minted seconds earlier.** The
  protection reads the TLS fingerprint of whoever arrives carrying the cookie, and it
  stopped accepting the one this Actor presented. Measured on a single jar and a single
  exit IP: `firefox133` returned the 297 KB page while `firefox147`, `firefox135` and
  `chrome` each got the 766-byte challenge — the day before, `firefox147` had worked all
  day. The client now walks a chain of fingerprints the moment a response comes back
  blocked and keeps the first one that gets through, so a flip like this costs one extra
  request instead of a run that returns nothing. Re-establishing access in a browser
  stays the last resort, not the first.

### 1.3.6 (2026-09-15) — G2 stopped letting the Actor in; it does again

- **Runs came back with nothing.** G2's bot protection started answering this Actor with a
  captcha page that never clears itself, so every run spent its whole budget opening
  browser sessions and pushed zero records. Two things were giving the run away, and both
  are fixed:
  - **The browser claimed to be a Windows machine while running in a Linux container**,
    where text is rasterised differently, the font list is nothing like a desktop's, and
    WebGPU and WebGL are missing entirely. It now presents a profile that matches the
    machine it actually runs on — a real display, WebGPU enabled, Microsoft's own fonts
    installed. Measured over 18 exit IPs before the change: not one got through.
  - **The exit IP.** Apify's residential pool is spent for this site — twenty exits in a
    row answered with a captcha. **Paying users now ride a premium proxy pool** that is
    let through, which is what makes runs return data again (a full run: access
    established after 12 exits, records pushed). Free users stay on Apify Residential,
    and a run that cannot establish access says exactly that instead of finishing silently
    with nothing.
- **A rejected exit IP costs seconds, not a minute.** The captcha page is recognised
  immediately instead of being waited out, so one run walks twenty exits in the time it
  used to spend on three.

### 1.3.5 (2026-09-15)

- **A blocked exit IP no longer costs a minute of the run.** G2's bot protection answers a
  browser in one of two ways: a challenge that clears itself in about ten seconds, or a
  captcha page that never clears on its own. The Actor waited out the full minute either
  way, so a run spent its whole budget on three or four dead IPs. It now recognises the
  captcha immediately and moves to the next IP, which lets one run try three times as many
  exits in the same time — and says so in the log instead of reporting a bare timeout.

### 1.3.4 (2026-08-27)

- **Fixed: runs that hung on start-up and were killed as timed out.** The container was started through `xvfb-run`, which every so often never handed over to Python - the run then sat there emitting nothing at all until the platform killed it. Camoufox runs headless and never needed a display, so the wrapper is gone and Python is started directly. The log is also unbuffered now, and its first line is written before anything heavy is imported, so a run that does die early says how far it got.
- **Long runs finish instead of being killed.** The Actor watches its own time limit and wraps up shortly before it, so everything collected so far is delivered and the run ends as succeeded. Previously a big job - every review of a product that has tens of thousands, say - could still be working when the limit arrived and was reported as a failure.
- **A wedged browser can no longer hold a run open.** Establishing access is capped at four minutes (a healthy hand-shake takes 40-60s) and at whatever time the run has left, and is not attempted more than six times in one run.

### 1.3 (2026-08-24)

- **Ratings per criterion on product profiles.** `criteriaRatings` now carries Meets Requirements, Ease of Use, Ease of Setup, Ease of Admin, Quality of Support, "good partner in doing business" and Product Direction - each scored out of 10 with the number of reviews behind the score. G2 publishes these only on its comparison pages, so they were previously unavailable. Comparison listings return the same block for every product on the page, alongside `hasFreeTrial`.
- **Star-by-star distribution.** `ratingDistribution` gives the review count and the share of all reviews for 5, 4, 3, 2 and 1 star.
- **Pros and cons themes with counts.** `prosAndCons` returns G2's review-derived themes with the side (pro or con) and how many reviews mention each, and `aiReviewSummary` returns G2's own summary of what reviewers say. Both also come with category listing rows.
- **Richer product profiles.** New: `description` (the vendor's own text), `features` (the rated feature checklist, grouped by feature category), `integrations` (every integration G2 lists, with its slug), `languagesSupported`, `solutionType`, `isAiVerified`, `featuredCompanies`, `topComparisons` and `hasFreeTrial`.
- **Listing rows are no longer just a ranked list.** Every row now carries `sellerName`, `sellerUrl`, `imageUrl`, `description`, `productId`, `productUuid`, `vendorId`, `productType`, `solutionType` and `isAiVerified`. Category rows add `categoryId`; search rows add `relatedCategories`; alternatives rows add `comparisonVerdicts` (how reviewers rate the alternative against your product) and `commonCategories`.
- **Category listings return ratings again.** G2 changed the markup of its category cards and the star rating stopped being picked up; category rows now carry `rating` and `reviewCount` as they should.
- **Reviews**: new `validationMethod` (how G2 verified the reviewer - LinkedIn, a business email account, ...), `reviewerAvatarUrl` and `vendorResponseAuthor`. `vendorResponse` is now just the reply text, without the "Response from ..." heading and the admin-only edit link that used to be glued to it.
- **Category directory**: rows now include `categoryId` and `parentCategory`, and only real directory entries are returned - the navigation and footer links G2 renders on the same page are no longer emitted as categories.
- **Alternatives** no longer list the product you asked about as its own alternative.
- Removed `switchedFrom` / `switchedTo` (and their heading fields): G2 retired the endpoint that served the switching chart, so the actor can no longer produce them. Dropping the request also makes every product profile one page faster. `helpfulVotes` is gone for the same reason - G2 no longer shows helpful counts on reviews.

### 1.2 (2026-08-02)

- Pay-per-event billing: you are charged per delivered record, by kind (review, product, listing item, alternative, category). A run stops as soon as it reaches the maximum charge you set, so it can never quietly overrun your budget.

### 1.1 (2026-08-02)

- **One input field for everything.** `targets` now accepts product URLs and slugs, category URLs and slugs, G2 search URLs, comparison URLs and plain search phrases, mixed together — each entry is recognised automatically. Replaces the four separate list fields.
- **Two steps in one run.** Start from a category, search or comparison and ask for Reviews or Profiles: the actor walks the listing and then scrapes every product it found, no copying URLs between runs. Bounded by `maxProductsToFollow`.
- **One mode, one record type.** Reviews mode returns reviews, profiles mode returns products, listing mode returns product lists, alternatives mode returns competitors. Nothing else is mixed in, so a run's dataset is already a single clean table. The four "extra data" toggles are gone with it.
- The review breakdown (counts by company size, reviewer role, industry, region and category) and the switching data are now fields on the product record, where they belong, instead of a separate record type.
- You now get only the record type you asked for: when a category or search is just the starting point, its listing rows are used to find products and are no longer written to the dataset. Use `scrapeType: "listing"` when the product list is what you want.
- **Much faster and cheaper runs.** Sessions used to be dropped every few pages, so a 10-product run re-authenticated ten times (326s). Requests now present a consistent browsing context and run one at a time, cutting that to a single authentication (127s) for the same work.
- The session is cached in its current, still-valid state, so consecutive runs reuse it instead of authenticating again.
- Faster startup: the container image no longer ships Playwright's three unused browsers, cutting roughly 1 GB from every image pull.
- Reviews are now de-duplicated by review ID across the whole run.

### 1.0 (2026-08-01)

- Initial release.
- **Reviews**: full review text (what they like, what they dislike, problems solved), star rating, headline, publish and update dates, reviewer name, job title, industry, company size segment, verification badges, review source, vendor replies and video flags — 30+ fields per review.
- **Product profiles**: overall rating, total review count, every G2 category, top pros and cons, published pricing plans with billing units, entry price, seller, integration count, logo and tagline.
- **Review statistics**: review counts broken down by company size, reviewer role, industry, region and category.
- **Switching data**: what buyers used before a product and what they moved to, with counts.
- **Listings**: products in a category (with G2's "best for" summaries), search results, ranked alternatives and competitors, and product comparisons.
- Filters for star rating, company size, reviewer role and region, plus four sort orders.
- Collects past G2's 100-reviews-per-view ceiling by slicing along its filter axes.
- Results stream to the dataset as they are parsed, so data is usable while the run is still going.
