More ways to include hidden identifiers:
Change the names of CSS classes or id attributes. Instead of <span class="smallcaps"> or <h1 id="chapter_1"> you could have <span class="smallcaps_abcd"> or <h1 id="chapter_1_abcd">, where "abcd" is an identifier specific for each copy.
Have two or more classes with different names but exactly the same CSS, and have the exact appearance of one or the other be a code to idenitify each copy. If you have 20 cases of <span class="smallcaps">, make them <span class="smallcaps1"> and <span class="smallcaps2"> instead, that makes room for 2^20 = more than 1 million different combinations.
More subtly, whether or not a fullstop is included in an HTML tag is sometimes unnoticeable, the code can be included in the instances of "<em>italic</em>
." and "<em>italic
.</em>".
You could add unstyled <span> tags around selected letters of the text, like this:
Code:
I en<span>jo</span>y my eig<span>h</span>t-a<span>n</span>d-a-half hour<span>s</span> of sleep <span>m</span>ost happ<span>i</span>ly, but i<span>t h</span>urts.
If you take only the letters in the tags, it spells "johnsmith", but it's invisible in the book, and could be far from obvious in the code, unless you know what to look for.
Any of these methods can be defeated if the user actually modifies the code (HTML/CSS) of the book, but they'd work if the book is just uploaded as-is.